Отложенные объекты (Deferred objects) в jQuery представляют собой инструмент для управления асинхронными операциями, позволяющий контролировать цепочки выполнения кода, обрабатывать успешное завершение, ошибки и промежуточные состояния. Они облегчают работу с асинхронными событиями, такими как AJAX-запросы, таймеры и другие операции, которые не завершаются мгновенно.
Объект jQuery.Deferred создаётся с помощью вызова:
var deferred = $.Deferred();
Deferred имеет три основных состояния:
Состояние объекта изменяется с помощью методов:
resolve([value]) — переводит Deferred в состояние
resolved и передает результат в обработчики успеха.reject([reason]) — переводит Deferred в состояние
rejected и передает причину ошибки в обработчики неудачи.notify([progress]) — сообщает о промежуточном прогрессе
операции.Deferred позволяет регистрировать функции, которые будут вызваны при изменении состояния:
deferred.done(function(result) {
console.log("Успех:", result);
}).fail(function(error) {
console.log("Ошибка:", error);
}).progress(function(status) {
console.log("Прогресс:", status);
});
Методы done, fail и progress
могут вызываться несколько раз, добавляя обработчики к соответствующим
событиям. Если Deferred уже завершён, новые обработчики вызываются
немедленно.
Наиболее распространённый сценарий использования Deferred — интеграция с AJAX-запросами:
function fetchData(url) {
var deferred = $.Deferred();
$.ajax({
url: url,
method: 'GET'
}).done(function(data) {
deferred.resolve(data);
}).fail(function(jqXHR, textStatus) {
deferred.reject(textStatus);
});
return deferred.promise();
}
fetchData('/api/data')
.done(function(data) {
console.log("Данные получены:", data);
})
.fail(function(error) {
console.log("Ошибка запроса:", error);
});
Метод promise() возвращает только интерфейс для
чтения объекта Deferred, что предотвращает внешнее изменение
состояния.
Deferred поддерживает последовательное выполнение асинхронных
операций через метод then:
$.Deferred()
.then(function() {
return $.Deferred(function(d) {
setTimeout(() => d.resolve("Этап 1"), 1000);
});
})
.then(function(result) {
console.log(result); // Этап 1
return "Этап 2";
})
.then(function(result) {
console.log(result); // Этап 2
});
Метод then позволяет:
doneCallback, failCallback,
progressCallback.whenФункция $.when используется для одновременного
отслеживания нескольких Deferred объектов:
var d1 = $.Deferred();
var d2 = $.Deferred();
$.when(d1, d2).done(function(r1, r2) {
console.log("Оба завершены:", r1, r2);
});
setTimeout(() => d1.resolve("Результат 1"), 500);
setTimeout(() => d2.resolve("Результат 2"), 1000);
Если один из Deferred отклоняется, цепочка $.when
автоматически переходит в состояние rejected.
promise() вместо полного Deferred, чтобы
сохранить инкапсуляцию.then для упрощения
последовательного выполнения асинхронных задач и избегания «адской
пирамиды колбеков».Методы jQuery AJAX ($.ajax, $.get,
$.post) уже возвращают Deferred объекты, что позволяет их
напрямую использовать в цепочках:
$.get('/api/data')
.done(function(data) { console.log("Данные:", data); })
.fail(function() { console.log("Ошибка запроса"); });
Это устраняет необходимость вручную создавать Deferred и оборачивать запросы.
Deferred в jQuery формирует основу для современного подхода к асинхронному программированию до появления нативных Promise в JavaScript, обеспечивая совместимость с существующими библиотеками и кодовой базой.