jQuery.deferred

В 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("время истекло"); });

Ещё один пример:

/**
 * Показ модального окна подтверждения
 *
 * @since  
 * @author bullgare
 * @param HTML Content
 * @param string Title
 * @param string ApproveCaption название кнопки подтверждения
 * @param string RejectCaption название кнопки удаления
 * @return jQuery.Promise @link http://api.jquery.com/Types/#Promise
 */
	function showModalPrompt( Content, Title, ApproveCaption, RejectCaption )
	{
		"use strict";
		var $ = jQuery;
		var $approveButton = $( '<button class="btn gray">' + ( ApproveCaption ? ApproveCaption : 'Подтвердить' ) + '</button>' ),
			$rejectButton = $( '<button class="btn gray">' + ( RejectCaption ? RejectCaption : 'Отмена' ) + '</button> ),
			$wrapper = $( '<div />' ),
			deferred = $.Deferred();

		$wrapper.
			html( '<div>' + Content + '</div>' ).
			append(
				$( '<div />' ).
					append( $approveButton ).
					append( $rejectButton )
			);

		$wrapper.
			ModalPopup( { title: Title } ).
			bind( 'popupclose.ModalPopup', function()
				{
					if ( ! deferred.isRejected() && ! deferred.isResolved()  ) {
						deferred.reject();
					}
				}
			);

		$approveButton.click( function() { deferred.resolve(); $wrapper.ModalPopup( 'close' ); } );
		$rejectButton.click( function() { deferred.reject(); $wrapper.ModalPopup( 'close' ); } );

		return deferred.promise();
	}
//===========================================================================}}}

Более подробно почитать можно:
на странице списка изменений jQuery 1.5 (почти все изменения и связаны с внедрением deferred),
jQuery Deferred Object (подробное описание),
Использование Deferred объектов в jQuery 1.5

LEAVE A COMMENT