В jQuery 1.5 была полностью переработана модель асинхронных запросов. Теперь они возвращают deferred-объект, содержащий promise-объект, который содержит методы, позволяющие узнать состояние запроса или навесить дополнительные обработчики. promise-Объект содержит методы then, done, fail, isResolved и isRejected.
Суть нового подхода состоит в следующем:
$.when($.ajax("/page1.php"), $.ajax("/page2.php")).done(function(a1, a2){
// a1 и a2 - аргументы, отвечающие соответственно за запросы к страницам page1 и page2
var jqXHR = a1[2]; /* массив состоит из [ "success", statusText, jqXHR ] */
if ( /Оппа!/.test(jqXHR.responseText) ) {
alert("Где-то на первой странице есть 'Оппа!'.");
}
});
$.when принимает deferred-объект или объекты и возвращает promise-объект.
Можно делать и так:
var $promise;
if ( tt == 1 ) {
$promise = $.when( $.getJSON( ... ) );
}
else if ( tt == 2 ) {
$promise = $.when( $.getJSON( ... ), $.getJSON( ... ), $.post( ... ) );
}
else {
$promise = $.when( console.log( 'else' ) );
}
$promise.
then( function() { console.log( 'done', data ) } );
Пример немного корявый, но сделан был для того, чтобы показать, что необязательно работать с асинхронными запросами для использования $.when-$.then.
Если $.when принимает в качестве аргумента не deferred-объект, то $.then выполнится сразу же.
Если передано несколько ajax-аргументов, то будет ожидаться завершение всех, и только после этого сработает функция (собственно, это основная фишка).
Можно создавать свои deferred-объекты:
// запуск задач через 3 секунды
function test() {
var d = $.Deferred();
setTimeout( function() { d.resolve(); }, 3000 );
return d.promise();
}
var t = test().done(function() { alert("время истекло"); });
Более подробно почитать можно:
на странице списка изменений jQuery 1.5 (почти все изменения и связаны с внедрением deferred),
jQuery Deferred Object (подробное описание),
Использование Deferred объектов в jQuery 1.5