Методы resolve и reject

В библиотеке jQuery методы resolve и reject являются ключевыми компонентами системы Deferred, предназначенной для управления асинхронными операциями. Они позволяют создавать цепочки обработчиков, управлять состоянием промисов и корректно обрабатывать успешные и ошибочные завершения асинхронных процессов.


Объект Deferred

Объект Deferred создается с помощью функции:

var deferred = $.Deferred();

Он представляет собой контролируемый промис, который может находиться в одном из трёх состояний:

  • pending — ожидание завершения;
  • resolved — успешное завершение;
  • rejected — завершение с ошибкой.

Методы resolve и reject используются для перевода объекта Deferred из состояния pending в соответствующее конечное состояние.


Метод resolve

Метод resolve переводит объект Deferred в состояние resolved, что означает успешное выполнение операции. После вызова resolve все зарегистрированные обработчики успеха (done) будут выполнены.

Пример:

var deferred = $.Deferred();

deferred.done(function(result) {
    console.log("Успех:", result);
});

deferred.resolve("Данные успешно загружены");

Особенности метода resolve:

  • Можно передавать любые данные, которые будут переданы обработчикам done.
  • Вызов resolve более одного раза не изменяет состояние Deferred; первый вызов фиксирует состояние.

Пример с несколькими обработчиками:

var deferred = $.Deferred();

deferred.done(function(result) {
    console.log("Первый обработчик:", result);
});

deferred.done(function(result) {
    console.log("Второй обработчик:", result);
});

deferred.resolve("Готово");
// Консоль:
// Первый обработчик: Готово
// Второй обработчик: Готово

Метод reject

Метод reject переводит объект Deferred в состояние rejected, сигнализируя о возникновении ошибки или невозможности завершить операцию. После вызова reject выполняются все обработчики ошибок (fail).

Пример:

var deferred = $.Deferred();

deferred.fail(function(error) {
    console.log("Ошибка:", error);
});

deferred.reject("Сбой при загрузке данных");

Особенности метода reject:

  • Можно передавать аргументы, которые будут переданы обработчикам fail.
  • Состояние rejected фиксируется первым вызовом метода reject; последующие вызовы игнорируются.
  • Если Deferred уже находится в состоянии resolved, вызов reject не имеет эффекта.

Взаимодействие с методами done и fail

Методы resolve и reject тесно связаны с регистрацией обработчиков:

  • done(handler) — добавляет обработчик, вызываемый при успешном завершении (resolve).
  • fail(handler) — добавляет обработчик, вызываемый при ошибке (reject).

Пример комбинированного использования:

var deferred = $.Deferred();

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

// Симулируем успешное завершение
deferred.resolve("Данные загружены");

// Симулируем ошибку после успешного завершения
deferred.reject("Это не сработает");

Результат выполнения:

Успех: Данные загружены

Метод reject после resolve не выполняет обработчики fail, так как состояние уже изменено на resolved.


Передача нескольких аргументов

Методы resolve и reject поддерживают передачу нескольких аргументов:

var deferred = $.Deferred();

deferred.done(function(a, b) {
    console.log("Аргументы:", a, b);
});

deferred.resolve("Первый", "Второй");
// Консоль: Аргументы: Первый Второй

Это полезно при передаче комплексных данных, например, при работе с результатами нескольких асинхронных операций одновременно.


Метод promise

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

var deferred = $.Deferred();
var promise = deferred.promise();

promise.done(function(result) {
    console.log("Результат:", result);
});

// Только объект deferred может вызвать resolve
deferred.resolve("Данные готовы");

Методы resolve и reject остаются доступными только для самого объекта Deferred, что помогает отделить производителя от потребителя асинхронных данных.


Применение в цепочках асинхронных операций

Методы resolve и reject позволяют строить цепочки промисов с помощью then:

var deferred = $.Deferred();

deferred.then(
    function(result) { console.log("Успех:", result); },
    function(error) { console.log("Ошибка:", error); }
);

deferred.resolve("Завершено успешно");

then принимает два аргумента:

  • Первый — функция, вызываемая при resolve.
  • Второй — функция, вызываемая при reject.

Такой подход позволяет организовывать сложные асинхронные сценарии с последовательной обработкой успеха и ошибок.


Практическая схема использования

  1. Создается Deferred для асинхронной операции.
  2. Регистрация обработчиков через done, fail или then.
  3. Внутри операции вызывается resolve при успешном завершении или reject при ошибке.
  4. Цепочка обработчиков автоматически получает переданные данные и выполняется соответствующим образом.

Пример с имитацией AJAX-запроса:

function fetchData() {
    var deferred = $.Deferred();

    setTimeout(function() {
        if (Math.random() > 0.5) {
            deferred.resolve("Данные успешно получены");
        } else {
            deferred.reject("Ошибка загрузки данных");
        }
    }, 1000);

    return deferred.promise();
}

fetchData().then(
    function(result) { console.log("Успех:", result); },
    function(error) { console.log("Ошибка:", error); }
);

Такой паттерн позволяет чисто разделять логику обработки успеха и ошибки, повышает читаемость кода и упрощает масштабирование асинхронных процессов.


Методы resolve и reject в jQuery обеспечивают гибкий и контролируемый механизм управления асинхронными событиями, позволяя создавать надежные и легко сопровождаемые приложения на JavaScript. Они являются основой всех современных подходов к промисам и Deferred в экосистеме jQuery.