jQuery метод .then()

Определение и применение

jQuery метод .then() добавляет обработчик или обработчики, вызываемые когда объект Deferred имеет состояние resolved (успешное выполнение), rejected (выполнение отклонено), или находится на стадии выполнения.

В jQuery 3 обработчики .then() выполняются асинхронно и создают новую цепочку Promise. Возвращённое обычное значение становится её успешным результатом, в том числе после обработки ошибки; выброшенное исключение отклоняет новую цепочку. Методы .done() и .fail() не преобразуют результат таким образом.

jQuery синтаксис:

Синтаксис 1.8:

JavaScript
deferred.then( doneFilter )
deferred.then( doneFilter, failFilter )
deferred.then( doneFilter, failFilter, progressFilter )

doneFilter - Function

failFilter - Function

progressFilter - Function

Начиная с версии jQuery 1.8 метод .then() возвращает объект Promise, который может фильтровать состояние и значения объекта Deferred с использованием функции. Обратные вызовы выполняются в порядке их добавления, другие методы объекта Promise могут быть добавлены по цепочке, включая дополнительные методы .then().

Добавлен в версии jQuery

1.8 (синтаксис существовааший в версиях jQuery 1.5 - 1.7 изменен). До версии jQuery 1.8 аргументы могли быть как функцией, так и массивом функций.

Значения параметров

Параметр Описание
doneFilter Функция, которая вызывается при изменении состояния объекта Deferred на resolved (успешное выполнение).
failFilter Функция, которая вызывается при изменении состояния объекта Deferred на rejected (выполнение отклонено). Необязательный параметр.
progressFilter Функция, которая вызывается когда объект Deferred создает уведомления о ходе выполнения (методы .notify()) и .notifyWith(). Необязательный параметр.

Пример использования

HTML
<!DOCTYPE html>
<html>
  <head>
    <title>Использование jQuery метода .catch()</title>
    <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
    <script>
      $(document).ready(function () {
        $(".test").click(function () {
          // задаем функцию при нажатиии на элемент с классом .comments
          $.get("https://jsonplaceholder.typicode.com/notexist") // пытаемся загрузить данные с сервера с помощью HTTP запроса методом GET
            .then(function () {
              // добавляем обработчик при удачном выполнении запроса
              console.log("выполнение успешно"); // выводим в консоль текстовую информацию
            })
            .catch(function () {
              // добавляем обработчик при отклонении  запроса
              console.log("выполнение отклонено"); // выводим в консоль текстовую информацию
            })
            .then(
              function () {
                // добавляем обработчик при удачном выполнении запроса
                console.log("ну и ладно"); // выводим в консоль текстовую информацию
              },
              function () {
                // добавляем обработчик при отклонении  запроса
                console.log("не может быть!"); // выводим в консоль текстовую информацию
              },
            );
        });
      });
    </script>
  </head>
  <body>
    <button class="test">Клик</button>
  </body>
</html>

В этом примере с использованием jQuery функции $.get() мы при нажатии на элемент <button> (кнопка) пытаемся загрузить данные с сервера с помощью HTTP запроса методом GET. В случае успешной загрузки данных (состояние объекта Deferred изменится на resolved) будет вызван первый и второй метод .then().

В нашем примере мы отправляем GET запрос на несуществующий адрес, что приводит к тому, что состояние объекта Deferred изменяется на rejected (выполнение отклонено). В результате чего, первый метод .then() будет проигнорирован, так как он не имеет фильтра для случая, когда состояние объекта объекта Deferred изменяется на rejected (выполнение отклонено), в связи с этим далее по цепочке будет вызван метод .catch(), который выводит текстовую информацию в консоль.

Обратите внимание, что последний метод .then() имеет фильтры как для успешного запроса, так и для случая, когда этот запрос будет отменен. В нашем случае будет всегда вызываться обработчик, предназначенный для удачного выполнения запроса, так как до него мы вызываем метод .catch(), который обрабатывает неудачное выполнение запроса.

В следующем примере мы рассмотрим с Вами как c помощью метода .then() фильтровать полученное значение:

Метод .then() — пример 2

Нажмите ▶. Используйте кнопки в результате и наблюдайте изменения. Измените JavaScript и запустите пример повторно. Используется jQuery 4.0.0.

index.html
HTML
<button class="resolve">Resolve</button>
<button class="reject">Reject</button>
<button data-example-event-0="">Page reload</button>
main.js
JavaScript
$(document).ready(function () {
    let dfd = $.Deferred() // создаем объект Deferred

    dfd.then(
        (val) => val * 10, // функция, которая вызывается при изменении состояния объекта Deffered на resolved
        (val) => val / 10,
    ) // функция, которая вызывается при изменении состояния объекта Deffered на rejected
        .then((val) => $('p').html(val)) // добавляем отфильтрованное содержимое в элемент <p>
        .then(() => console.log(dfd.state())) // выводим в консоль текущее состояние выполнения объекта Deffered

    $('.resolve').click(function () {
        // задаем функцию при нажатиии на элемент с классом .resolve
        dfd.resolve(100) // изменяем состояние объекта Deffered на resolve и передаем значение
    })
    $('.reject').click(function () {
        // задаем функцию при нажатиии на элемент с классом .reject
        dfd.reject(100) // изменяем состояние объекта Deffered на reject и передаем значение
    })
})

document.querySelector('[data-example-event-0]').addEventListener('click', function (event) {
    window.location.reload()
})
style.css
CSS
body {
  margin: 16px;
  font:
    16px/1.5 system-ui,
    sans-serif;
  overflow-wrap: anywhere;
}
img,
input,
select,
textarea,
button {
  max-width: 100%;
}

В этом примере мы инициализируем переменную, которая содержит объект Deferred, созданный с помощью фабричной функции $.Deferred().

При нажатии на определенный элемент <button>, благодаря установленному обработчику событий "click" на элементе мы в первом случае с помощью метода .resolve() изменяем состояние объекта Deferred на resolved (успешное выполнение) и передаем числовое значение 100, а во втором случае с помощью метода .reject() изменяем состояние объекта Deferred на rejected (выполнение отклонено) и передаем то же значение.

С помощью первого вызова метода .then() на объекте Deferred мы устанавливаем два фильтра, первый из них (doneFilter) определяет функцию, которая вызывается при изменении состояния объекта Deferred на resolved (успешное выполнение), а второй (failFilter) определяет функцию, которая вызывается при изменении состояния объекта Deferred на rejected (выполнение отклонено). При успешном выполнении (resolved) переданное значение будет умножено на 10, а при отклонении выполнения (rejected) значение будет поделено на 10. Обратите внимание, что мы используем стрелочные функции, они позволяют сделать код более компактным и читаемым.

После этого с помощью следующего вызова метода .then() мы с помощью метода .html() добавляем полученное значение в элемент <p>, и следующим вызовом метода .then() с помощью метода .state() объекта Deferred выводим в консоль текущее состояние выполнения объекта Deferred.