jQuery предоставляет собственный механизм работы с асинхронными
операциями через объект Deferred, который
реализует паттерн промисов. Этот механизм позволяет последовательно
выполнять асинхронные действия, обрабатывать успешное завершение и
ошибки, а также комбинировать несколько операций в цепочки.
Объект Deferred создаётся вызовом:
var deferred = $.Deferred();
Чтобы получить промис из этого объекта, используется метод
promise():
var promise = deferred.promise();
Промис предоставляет методы для подписки на завершение операции:
done(callback) — вызывается при
успешном завершении.fail(callback) — вызывается при
ошибке.always(callback) — вызывается в любом
случае.Методы then,
done и fail
позволяют создавать цепочки:
$.ajax("/data.json")
.then(function(response) {
console.log("Данные получены:", response);
return $.ajax("/additional.json");
})
.then(function(additionalData) {
console.log("Дополнительные данные:", additionalData);
})
.fail(function(error) {
console.error("Произошла ошибка:", error);
});
В этом примере каждая следующая операция выполняется после успешного
завершения предыдущей. Если на любом шаге возникает ошибка, вызывается
блок fail, и дальнейшие шаги цепочки не
выполняются.
thenМетод then может возвращать как обычное
значение, так и новый промис. Это позволяет строить более сложные
последовательности:
$.ajax("/user.json")
.then(function(user) {
return $.ajax("/orders.json?userId=" + user.id);
})
.then(function(orders) {
console.log("Список заказов:", orders);
});
Если в then возвращается промис,
следующий шаг цепочки ждёт его выполнения. Если возвращается обычное
значение, оно передаётся следующему шагу как результат.
jQuery позволяет обрабатывать ошибки на любом шаге цепочки. Методы
fail и
then(null, onRejected) выполняют одну и ту
же функцию:
$.ajax("/data.json")
.then(
function(data) { console.log("Данные:", data); },
function(err) { console.error("Ошибка загрузки:", err); }
);
При использовании цепочек часто применяется общий блок
fail в конце, чтобы централизованно
обработать все ошибки.
Метод $.when позволяет запускать
несколько асинхронных операций параллельно и получать результат, когда
все они завершены:
$.when($.ajax("/users.json"), $.ajax("/orders.json"))
.then(function(users, orders) {
console.log("Пользователи:", users[0]);
console.log("Заказы:", orders[0]);
})
.fail(function() {
console.error("Ошибка при загрузке данных");
});
Метод $.when возвращает промис, который
считается выполненным, если все переданные промисы завершились успешно.
Если хотя бы один промис завершается ошибкой, срабатывает блок
fail.
Промисы позволяют изменять данные на каждом шаге цепочки, что делает их мощным инструментом для обработки асинхронных потоков:
$.ajax("/users.json")
.then(function(users) {
return users.map(user => user.id);
})
.then(function(userIds) {
return $.when(...userIds.map(id => $.ajax("/orders.json?userId=" + id)));
})
.then(function(...orders) {
console.log("Все заказы пользователей:", orders.map(o => o[0]));
});
Здесь сначала извлекаются идентификаторы пользователей, затем для каждого идентификатора загружаются заказы, а в конце объединяются результаты всех промисов.
then возвращает новый промис —
цепочки не изменяют исходный объект Deferred.fail.then.Цепочки промисов в jQuery обеспечивают структурированный и чистый подход к управлению асинхронностью, позволяя строить сложные последовательности запросов и операций без глубоких вложенностей и хаотичной логики.