Введение в промисы

Последнее обновление: 20.11.2023

Промис (promise) - это объект, представляющий результат успешного или неудачного завершения асинхронной операции. Асинхронная операция, упрощенно говоря, это некоторое действие, выполняется независимо от окружающего ее кода, в котором она вызывается, не блокирует выполнение вызываемого кода.

Промис может находиться в одном из следующих состояний:

  • pending (состояние ожидания): начальное состояние, промис создан, но выполнение еще не завершено

  • fulfilled (успешно завершено): действие, которое представляет промис, успешно завершено

  • rejected (завершено с ошибкой): при выполнении действия, которое представляет промис, произошла ошибка

Для создания промиса применяется конструктор типа Promise:

new Promise(executor)

В качестве параметра конструктор принимает функцию, которая выполняется при создании промиса. Обычно эта функция представляет асинхронные операции, которые занимают продолжительное время. Например, определим простейший промис:

const myPromise = new Promise(function(){
	console.log("Выполнение асинхронной операции");
});

Здесь функция просто выводит на консоль сообщение. Соответственно при выполнении этого кода мы увидим на консоли сообщение "Выполнение асинхронной операции".

При создании промиса, когда его функция еще не начала выполняться, промис переходит в состояние "pending", то есть ожидает выполнения.

Для эмуляции асинхронности определим несколько промисов:

const myPromise3000 = new Promise(function(){
	console.log("[myPromise3000] Выполнение асинхронной операции");
    setTimeout(()=>console.log("[myPromise3000] Завершение асинхронной операции"), 3000);
});
const myPromise1000 = new Promise(function(){
	console.log("[myPromise1000] Выполнение асинхронной операции");
    setTimeout(()=>console.log("[myPromise1000] Завершение асинхронной операции"), 1000);
});
const myPromise2000 = new Promise(function(){
	console.log("[myPromise2000] Выполнение асинхронной операции");
    setTimeout(()=>console.log("[myPromise2000] Завершение асинхронной операции"), 2000);
});

Здесь определены три однотипных промиса. Чтобы каждый из них не выполнялся сразу, они используют функцию setTimeout с задержкой в несколько секунд. Для разных промисов длительность задержки различается. И в данном случае мы получим следующий консольный вывод:

[myPromise3000] Выполнение асинхронной операции
[myPromise1000] Выполнение асинхронной операции
[myPromise2000] Выполнение асинхронной операции
[myPromise1000] Завершение асинхронной операции
[myPromise2000] Завершение асинхронной операции
[myPromise3000] Завершение асинхронной операции

Здесь мы видим, что первым начал выполняться промис myPromise3000, однако он же завершился последним, так как для него установлено наибольшее время задержки - 3 секунды. Однако его задержка не помешала выполнению остальных промисов.

resolve и reject

Как правило, функция, которая передается в конструктор Promise, принимает два параметра:

const myPromise = new Promise(function(resolve, reject){
	console.log("Выполнение асинхронной операции");
});

Оба этих параметра - resolve и reject также представляют функции. И каждая из этих функций принимает параметр любого типа.

Первый параметр - функция resolve вызывается в случае успешного выполнения. Мы можем в нее передать значение, которое мы можем получить в результате успешного выполнения.

Второй параметр - функция reject вызывается, если выполнение операции завершилось с ошибкой. Мы можем в нее передать значение, которое представит некоторую информацию об ошибке.

Успешное выполнение промиса

Итак, первый параметр функции в конструкторе Promise - функция resolve выполняется при успешном выполненим. В эту функцию обычно передается значение, которое представляет результат операции при успешном выполнении. Это значение может представлять любой объект. Например, передадим в эту функцию строку:

const myPromise = new Promise(function(resolve){
	console.log("Выполнение асинхронной операции");
	
	resolve("Привет мир!");
});

Функция resolve() вызывается в конце выполняемой операции после всех действий. При вызове этой функции промис переходит в состояние fulfilled (успешно выполнено).

При этом стоит отметить, что теоретически мы можем возвратить из функции результат, но практического смысла в этом не будет:

const myPromise = new Promise(function(resolve, reject){
	console.log("Выполнение асинхронной операции");
	
	return "Привет мир!";
});

Данное возвращаемое значение мы не сможем передать во вне. И если действительно надо возвратить какой-то результат, то он передается в функцию resolve().

Передача информации об ошибке

Второй параметр функции в конструкторе Promise - функция reject вызывается при возникновении ошибки. В эту функцию обычно передается некоторая информация об ошибке, которое может представлять любой объект. Например:

const myPromise = new Promise(function(resolve, reject){
	console.log("Выполнение асинхронной операции");
	reject("Переданы некорректные данные");
});

При вызове функции reject() промис переходит в состояние rejected (завершилось с ошибкой).

Объединение resolve и reject

Естественно мы можем определить логику, при которой в зависимости от условий будут выполняться обе функции:

const x = 4;
const y = 0;
const myPromise = new Promise(function(resolve, reject){

	if(y === 0)	{
		reject("Переданы некорректные данные");
	}
	else{
		const z = x / y;
		resolve(z);
	}
});

В данном случае, если значени константы y равно 0, то сообщаем об ошибке, вызывая функцию reject(). Если не равно 0, то выполняем операцию деления и передаем результат в функцию resolve().

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850