jQuery метод .then()

jQuery объект Deferred

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

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

jQuery синтаксис:

Синтаксис 1.8:

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

doneFilter - Function
failFilter - Function
progressFilter - Function

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


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

Для установки только одного типа обратного вызова без фильтрации состояния, или значений, Вы можете воспользоваться методами .done() - при изменении состояния объекта Deffered на resolved (успешное выполнение), .fail() - при изменении состояния объекта Deffered на rejected (выполнение отклонено) и .progress() (когда объект Deffered создает уведомления о ходе выполнения).


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

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

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

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

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

<!DOCTYPE html>
<html>
	<head>
		<title>Использование jQuery метода .catch()</title>
		<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.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. В случае успешной загрузки данных (состояние объекта Deffered изменится на resolved) будет вызван первый и второй метод .then().

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

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

Результат примера:

Пример использования jQuery метода .then()
Пример использования jQuery метода .then()

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

<!DOCTYPE html>
<html>
	<head>
		<title>Фильтрация значения методом .then()</title>
		<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
		<script>
	$( 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 и передаем значение
	  });
	});
		</script>
	</head>
	<body>
		<button class = "resolve">Resolve</button>
		<button class = "reject">Reject</button>
		<button onclick = window.location.reload()>Page reload</button>
	</body>
</html>

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

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

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

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

Результат примера:

Пример фильтрации значения методом .then()
Пример фильтрации значения методом .then()
jQuery объект Deferred