2016-01-20 2 views
0

Мне нужно задержать каждый вызов Ajax до тех пор, пока не будет выполнена предыдущая функция (hashcode.Sign()). К сожалению, мой код не дожидался завершения hashcode.Sign(), и это все испортило, поскольку эта функция создает новый сеанс и не может быть перезаписана для работы. Как мне это сделать? Я новичок в объектах с отсрочкой, поэтому прошу прощения за недостаток знаний.Как выстроить jQuery отложенные объекты?

for (var l = 0; l < fileArray.length; l++) { 
     var d = new jQuery.Deferred(); 
     d.resolve(openDdoc(fileArray[l].url, $pid, fileArray[l].id)); 
     d.done(function() { console.log('done'); }); 
    } 

    function openDdoc(url, pid, fid) { 
     var def = new jQuery.Deferred(); 
     $.when(def).done(function() { console.log('Function completed!'); }); 
     def.resolve($.ajax({ 
        url: '/open-ddoc', 
        type: 'post', 
        async: false, 
        data: {doc: url, pid: pid, fid: fid}, 
       }).done(function (data) { 
        hashcode.Sign(); 
       }).fail(function(data) { 
        console.log('this shit failed'); 
       })); 
    } 

hashcode.Sign() функция включает в себя еще несколько вызовов Ajax и вызовы других функций. Я могу включить его позже, если понадобится. Я знаю, что смогу решить все это с помощью setTimeout(), но это был бы не мой первый выбор.

+0

Да, пожалуйста, укажите 'hashcode.Sign()'. Важно, чтобы оно было написано правильно. –

ответ

2

Это не сразу очевидно, но последовательность, которую вы ищете, может быть выражена в виде fileArray().reduce(...).

Этот проверенный шаблон представлен here под заголовком "The Collection Kerfuffle". (Вся статья стоит прочитать).

fileArray.reduce(function(promise, file) { 
    return promise.then(function() { 
     return $.ajax({ 
      url: '/open-ddoc', 
      type: 'post', 
      async: true, // <<<<< always TRUE!! 
      data: {doc: file.url, pid: $pid, fid: file.id} 
     }); 
    }).then(function(data) { 
     console.log(file.id + ': done'); 
     return hashcode.Sign(); // hashcode.Sign() must return a promise 
    }); 
}, $.when()) // <<<<< resolved promise to get the chain started 
.then(function() { 
    console.log('all done'); 
}); 

В этой схеме каждый член fileArray посещает, в свою очередь (синхронно), добавляя свежий .then() к растущей цепи посыла на каждом визите.

Разрешенное обещание стартера, $.when(), заставляет сконструированную цепочку начать установку, а вызовы ajax выполняются последовательно.

Звонок ajax не обязательно должен находиться в отдельной функции, если только он не будет вызван в другом месте.

Следует подчеркнуть, чтоhashcode.Sign() (который мы понимаем, что асинхронный) должны быть написаны на правильном пути, так что он возвращает действительное обещание. Если нет, то процесс урегулирования не имеет возможности обеспечить его асинхронность (ы) для завершения до начала.

+0

Просто указывая очевидное: // hashcode.Sign() должен вернуть обещание, вероятно, является одним из наиболее важных моментов в этом ответе. Если 'hashcode.Sign()' не возвращает обещание, вы не можете сделать это, чтобы исправить это, кроме исправления 'hashcode.Sign()', чтобы вернуть обещание. –

+0

@KevinB, спасибо. Да, очевидно для вас и для меня, но, возможно, не для OP. На данный момент я добавил сноску. Когда OP ответит на мой запрос на код 'hashcode.Sign(), я смогу сделать подходящее редактирование. Если вы первый раз попадете туда, не стесняйтесь редактировать мой ответ. –

+0

Спасибо за солидный ответ. Я добавил [соответствующую функцию в PasteBin] (http://pastebin.com/dZS9BTED), чтобы вы могли посмотреть. На данный момент я должен признать, что это не возвращает обещание. – jeesus