2011-11-11 5 views
5

Я использую jQuery, и у меня есть цикл асинхронных запросов AJAX. Я знаю, что могу дождаться, когда все они будут закончены, используя удобный метод $ .when.apply (array_of_requests) .then().Как подождать, пока вложенные запросы async jQuery завершатся AJAX?

Но у меня также есть еще один набор запросов AJAX, которые выполняются только после завершения каждого из первых запросов. Я хочу подождать, пока они тоже закончатся, но я не уверен на 100%, что нашел лучший способ.

Вот упрощенный пример моих запросов:

var intital_data = [1,2,3,4,5,6,7,8,9,10]; 
var promises = []; 
var promises_inner = []; 

$.each(intitial_data, function(i, n) { 
    var ajax_call = $.ajax({url:'http://www.domain.com/etc/'+n}); 
    promises.push(ajax_call); 

    ajax_call.done(function(data) { 
     var ajax_call_inner = $.ajax({url:'http://www.domain.com/etc/'+data.result}); 
     promises_inner.push(ajax_call_inner); 

     ajax_call_inner.done(function(data) { 
      // Do something with the content of data here. 
     }); 
    }); 
}); 

Так что, когда каждый из десяти петельные AJAX запросов будет сделано, я делаю второй запрос AJAX на основе результатов первого. Все работает отлично.

я тогда что-то вроде этого, потому что я хочу, чтобы ждать, пока оба первых десяти запросов (хранится в массиве обещаний) и второй лот (хранится в promises_inner) завершены:

$.when.apply($, promises).then(
    function() { 
     // The ten outer AJAX calls are finished now. 

     $.when.apply($, promises_inner).then(
      function() { 
       // The inner AJAX calls are finished now. 
      } 
     ); 
    } 
); 

В первой функции $ .when.apply(). Then() 'done' вторая партия запросов еще не завершена или даже добавлена ​​в массив promises_inner. Но я обнаружил, что добавление вложенных $ .when.apply(). Then(), похоже, работает - в своей «готовой» функции все запросы завершены.

Но я не уверен, что это лучшее и самое надежное решение. Я беспокоюсь, что он работает только по совпадению - это вызывает достаточно задержки для завершения звонков, а не логического смысла.

Есть ли лучшее, более твердое твердое решение? Благодарю.

+0

я говорил слишком рано, когда я сказал, что это похоже на работу. Иногда это работает, но в других случаях, promises_inner не было все из вложенное объявление AJAX до сих пор. Поэтому иногда внутренние $. Происходит, прежде чем все будет возвращено. –

ответ

2

Взгляните на $ .Callbacks в 1.7. Я думаю, вы будете в восторге от гибкости создания собственных «потоков» и возможности их повторного использования, запускать один раз и т. Д.

Нет ничего плохого в том, что вы сделали (шаблон приложения может быть не первым выбором Большинство из них обычно просто перечисляют их в $ .when (a, b, c ....) - но вам может понравиться синтаксис $ .Callbacks лучше.

+0

Спасибо за указатель. Документы $ .Callbacks заставляют мой мозг ранить, но я ожидаю, что он утонет в конце концов! А пока, как вы думаете, мои вложенные $ .when должны быть надежными? –

+0

Мы должны делать подобные вещи при обработке правил в нашем страховом приложении, потому что есть как минимум 10 сервисов. Другая вещь, которую вы можете сделать, которая может быть легче читать, - это создать Отложенный и разрешить ее только при первом завершении. Используйте это обещание Отсрочка как .done для следующего набора обратных вызовов. У Адди Османи есть хорошая статья о Callbacks, и, скорее всего, еще больше. – AutoSponge

0

Попробуйте это только с одним основным обещанием FULLFILL (решительность) в петлевой перспективе (здесь до сих пор под названием inner_promise).

var initial_data = [1,2,3,4,5,6,7,8,9,10]; 
var promises_inner = []; 

initial_data.forEach(function(n) { 
    // Create promise for the inner call here. 
    var promise_inner = $.Deferred(); 
    promises_inner.push(promise_inner); 

    $.ajax({url:'http://www.domain.com/etc/'+n}).done(function(data) { 
     $.ajax({url:'http://www.domain.com/etc/'+data.result}).done(function(data) { 
      // Do something with the content of data here. 
      promise_inner.resolve(); 
     }); 
    }); 
}); 
console.log("promises_inner contains " + promises_inner.length + " promises") // should contain all the 10 promises 

$.when.apply($,promises_inner).done(function() { 
    // The inner AJAX calls are finished now 
}) 
Смежные вопросы