Deferred в jQuery представляет собой объект, предназначенный для управления асинхронными операциями. Он позволяет регистрировать функции обратного вызова (callbacks), которые будут вызваны после завершения операции, обработки ошибок или прогресса выполнения. Deferred обеспечивает более удобное и структурированное управление асинхронным кодом по сравнению с классическими колбэками.
Deferred тесно связан с понятием Promise, хотя имеет собственные расширения и возможности, характерные для jQuery. Основные состояния Deferred:
Для создания Deferred используется метод
$.Deferred().
var deferred = $.Deferred();
После этого объект deferred предоставляет методы для
управления состояниями и регистрации обработчиков:
resolved и вызывает все зарегистрированные функции успеха
(done).rejected и вызывает все функции отказа
(fail).progress).Deferred позволяет регистрировать функции обратного вызова через методы:
Пример:
var deferred = $.Deferred();
deferred.done(function(result) {
console.log("Операция успешна:", result);
}).fail(function(error) {
console.log("Ошибка выполнения:", error);
}).progress(function(status) {
console.log("Прогресс:", status);
});
// Симуляция асинхронной операции
setTimeout(function() {
deferred.notify("50% готово");
deferred.resolve("Готово");
}, 1000);
В данном примере сначала регистрируются обработчики, затем имитируется асинхронная операция, которая сначала сообщает о прогрессе, а потом завершает Deferred успешно.
promise()Deferred объект можно использовать совместно с промисами. Метод
promise() возвращает объект, который предоставляет только
интерфейс для регистрации обратных вызовов (done,
fail, progress), исключая методы управления
состояниями (resolve, reject). Это позволяет
передавать объект другим частям кода, не опасаясь, что его состояние
будет изменено извне.
var deferred = $.Deferred();
var promise = deferred.promise();
promise.done(function(result) {
console.log(result);
});
// Здесь невозможно вызвать deferred.resolve() через promise
Методы $.when() и then() позволяют
комбинировать несколько Deferred объектов.
var task1 = $.Deferred();
var task2 = $.Deferred();
$.when(task1, task2).done(function(result1, result2) {
console.log("Все задачи завершены:", result1, result2);
});
// Симуляция завершения задач
setTimeout(() => task1.resolve("Результат 1"), 1000);
setTimeout(() => task2.resolve("Результат 2"), 1500);
Метод then() позволяет цепочечно обрабатывать результаты
Deferred:
var deferred = $.Deferred();
deferred
.then(function(result) {
console.log("Шаг 1:", result);
return "Результат шаг 2";
})
.then(function(result) {
console.log("Шаг 2:", result);
});
deferred.resolve("Начальный результат");
Каждый then() возвращает новый Deferred, что позволяет
строить последовательные асинхронные цепочки.
Методы always(callback) и pipe()
обеспечивают дополнительную гибкость:
then) —
позволяет трансформировать результат Deferred и создавать новые
цепочки.var deferred = $.Deferred();
deferred.always(function(value) {
console.log("Завершено, независимо от результата:", value);
});
deferred.reject("Ошибка выполнения");
Deferred широко используется для управления асинхронными операциями:
$.ajax возвращает Deferred).Пример с AJAX:
$.ajax("/api/data")
.done(function(data) {
console.log("Данные получены:", data);
})
.fail(function() {
console.log("Ошибка запроса");
});
Такой подход позволяет писать более читаемый и управляемый асинхронный код, избегая “адов колбэков”.
Deferred является фундаментальным инструментом в jQuery для построения надежной асинхронной логики, обеспечивая гибкость и масштабируемость при работе с множеством асинхронных операций.