Последовательность отложенных обратных вызовов 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);