Последовательность отложенных обратных вызовов jQuery

Если у меня есть что-то вроде

var promise1 = $.ajax(...).done(callback1);
var promise2 = $.ajax(...).done(callback2);
$.when(promise1, promise2).done(callback3);

Гарантируется ли это, что callback3 побежит после callback1 а также callback2? (первые два обратных вызова могут выполняться в любом порядке, в зависимости от базового завершения AJAX.)

Кажется, что это имеет место в некоторых ограниченных тестах, но всегда ли это правда или совпадение? Другими словами, делает done вернуть новое обещание, которое разрешается после завершения обратного вызова?

2 ответа

Да. Обратные вызовы (за одно обещание) гарантированно будут выполняться в том же порядке, в котором они прикреплены. По крайней мере, спецификация диктует это для then и хотя jQuery не следует [всем] спецификациям Callbacks Объекты реализованы так.

Тем не менее, вы никогда не должны полагаться на это. Если callback3 зависит от результатов (действий) предыдущих обратных вызовов, это должно быть указано явно. Вы можете создавать обещания для результатов обратных вызовов с помощью then метод (ранее pipe):

$.when(
    $.ajax(…).then(callback1),
    $.ajax(…).then(callback2)
).done(callback3);

// more explicit:

var ajax1 = $.ajax(…),
    ajax2 = $.ajax(…),
    ajaxAndAction1 = ajax1.then(callback1),
    ajaxAndAction2 = ajax2.then(callback2),
    everything = $.when(ajaxAndAction1, ajaxAndAction2);
everything.done(callback3);

Если callback1 а также callback2 не выполняйте никаких асинхронных действий (таких как дополнительные запросы Ajax или анимации), вы можете использовать свой код и чувствовать себя комфортно, зная, что callback1 и 2 всегда будет завершено до callback3 выполняется с использованием существующего кода. Однако если callback1 и / или callback2 выполнять дальнейшие асинхронные действия, вам нужно использовать .then если вы хотите дождаться завершения дальнейших асинхронных действий.

function callback1 (data) {
    return $.ajax(...);
}
function callback2 (data) {
    return $.ajax(...);
}
var promise1 = $.ajax(...).then(callback1);
var promise2 = $.ajax(...).then(callback2);
$.when(promise1,promise2).done(callback3);
Другие вопросы по тегам