Несколько асинхронных операций

jQuery предоставляет удобные механизмы для работы с асинхронными операциями, такими как AJAX-запросы, анимации и отложенные функции. Для управления несколькими асинхронными процессами используется объект Deferred и его связанный интерфейс Promise. Они позволяют организовать последовательное или параллельное выполнение операций с контролем результатов и обработкой ошибок.


Объект Deferred

Deferred — это объект, представляющий отложенную операцию. Он позволяет регистрировать функции обратного вызова (callbacks) на успешное завершение, неудачу или прогресс выполнения.

Создание Deferred:

var deferred = $.Deferred();

Регистрация обработчиков:

deferred.done(function(result) {
    console.log("Успех:", result);
}).fail(function(error) {
    console.log("Ошибка:", error);
}).progress(function(status) {
    console.log("Прогресс:", status);
});

Разрешение или отклонение Deferred:

deferred.resolve("Данные получены");  // успешное завершение
deferred.reject("Произошла ошибка");   // ошибка
deferred.notify("50% готово");         // уведомление о прогрессе

Параллельное выполнение нескольких операций

Для выполнения нескольких асинхронных операций одновременно и обработки их результатов используется функция $.when. Она принимает любое количество объектов Deferred или Promise.

Пример с двумя AJAX-запросами:

var request1 = $.ajax("/api/data1");
var request2 = $.ajax("/api/data2");

$.when(request1, request2).done(function(response1, response2) {
    console.log("Ответ первого запроса:", response1);
    console.log("Ответ второго запроса:", response2);
}).fail(function() {
    console.log("Один или оба запроса завершились ошибкой");
});

$.when завершает выполнение только после того, как все переданные объекты будут разрешены (resolve). Если хотя бы один отклонён (reject), срабатывает fail.


Последовательное выполнение операций

Иногда требуется выполнять асинхронные действия поочередно, передавая результат предыдущей операции следующей. Для этого используют метод then.

Синтаксис then:

asyncOperation()
    .then(function(result1) {
        return nextAsyncOperation(result1);
    })
    .then(function(result2) {
        console.log("Финальный результат:", result2);
    })
    .fail(function(error) {
        console.error("Ошибка на каком-либо этапе:", error);
    });

Метод then позволяет:

  • Преобразовать результат предыдущей операции перед передачей дальше.
  • Возвращать новый Deferred, создавая цепочку асинхронных вызовов.
  • Обрабатывать ошибки на любом этапе цепочки с помощью fail.

Обработка прогресса

Для длительных операций удобно использовать уведомления о прогрессе через метод notify и регистрацию обработчика progress.

Пример:

function longTask() {
    var deferred = $.Deferred();
    var progress = 0;

    var interval = setInterval(function() {
        progress += 10;
        deferred.notify(progress + "% выполнено");

        if (progress >= 100) {
            clearInterval(interval);
            deferred.resolve("Задача завершена");
        }
    }, 100);

    return deferred;
}

longTask().progress(function(status) {
    console.log(status);
}).done(function(result) {
    console.log(result);
});

Это позволяет отображать пользователю индикатор прогресса, даже если операция полностью асинхронна.


Объединение разных типов Deferred

jQuery позволяет объединять различные источники асинхронных событий — AJAX-запросы, таймеры, анимации — в единый поток обработки.

Пример: AJAX + анимация:

var ajaxCall = $.ajax("/api/data");
var animation = $("#box").fadeOut(1000).promise();

$.when(ajaxCall, animation).done(function(data) {
    console.log("Данные получены, анимация завершена", data);
});

Метод .promise() у анимации возвращает Deferred, что позволяет использовать $.when для синхронизации с другими асинхронными действиями.


Резюме ключевых возможностей

  • $.Deferred() создаёт отложенную операцию с методами resolve, reject, notify.
  • Методы done, fail, progress регистрируют обработчики успешного завершения, ошибки и прогресса.
  • $.when() объединяет несколько Deferred и выполняет их параллельно.
  • then() позволяет строить цепочки асинхронных операций, передавая результаты последовательно.
  • Метод .promise() превращает объекты с асинхронным поведением (например, анимации) в совместимые Deferred.

Эти механизмы формируют основу для управления сложными асинхронными процессами в jQuery, обеспечивая читаемость кода и удобное управление результатами и ошибками.