Подождите, пока не будет разрешена первая из нескольких jQuery-отсрочек?

С jQuery я знаю, что я могу использовать $.when(), чтобы дождаться, когда будет разрешен весь файл multipe Deferred. (Или для первого отклоняется.)

Но есть ли простой способ запуска нескольких Deferred, а затем просто ждать, пока первый будет разрешен?

Например, я хочу попытаться использовать две аналогичные веб-службы AJAX, которые могут быть медленными или медленными, а затем обрабатывать в зависимости от того, что ответ сначала. И тогда я могу использовать третий Deferred для тайм-аута.

Ответ 1

Основываясь на коде Kevin B, здесь используется подход, который использует главный объект отложенного объекта:

var masterDeferred = new $.Deferred(),
    reqOne = $.post("foo.php"),
    reqTwo = $.post("bar.php");

masterDeferred.done(function() {
    // do stuff
});

reqOne.done(function() {
    masterDeferred.resolve();
});
reqTwo.done(function() {
    masterDeferred.resolve();
});

Я думаю, что я прав, говоря, что простейшей формой разрешения masterDeferred будет:

reqOne.done(masterDeferred.resolve);
reqTwo.done(masterDeferred.resolve);

Но отдельные выполненные функции позволят вам внутренне отлаживаться и называть .resolve(), .reject(), .resolveWith(...) или .rejectWith(...), а также masterDeferred обратные вызовы общего вида:

masterDeferred.then( doneCallbacks, failCallbacks );

Ответ 2

Быстрый и простой способ состоит в том, чтобы прервать другой запрос, когда один из двух финишей, хотя вы также можете проверить состояние отложенного, синтаксис которого будет зависеть от вашей версии jQuery, поэтому я иду с отменой пока.

function doStuff(data) {
    alert( "Hello World!" );
}
var reqOne = $.post("foo.php"),
reqTwo = $.post("bar.php");

reqOne.done(function(data){
    reqTwo.abort();
    finished = true;
    doStuff(data);
});
reqTwo.done(function(data){
    reqOne.abort();
    finished = true;
    doStuff(data);
});