Класс Promise в JavaScript
В этой статье мы объясняем класс Promise в JavaScript.
YouTube Video
Promise
Класс Promise
предназначен для обработки асинхронных операций. Он обрабатывает результаты при успешном завершении операции или ошибки при её сбое. Традиционно использовались функции обратного вызова, когда нужно было дождаться завершения асинхронной операции, но Promise
делает этот процесс более понятным и мощным.
1const promise = new Promise((resolve, reject) => {
2 setTimeout(() => resolve("Done!"), 1000);
3});
4
5// Displays "Done!" after 1 second
6promise.then(result => console.log(result));
- Этот код является примером асинхронного процесса, который выводит «Готово!» через одну секунду.
- Сначала создаётся новый объект
Promise
с помощьюnew Promise
. Аргументом является функция, принимающая два обратных вызова:resolve
для успешного завершения иreject
для ошибки. setTimeout
используется для вызоваresolve()
через одну секунду.- Метод
then()
объектаpromise
ждёт завершения и выводит результат.
- Сначала создаётся новый объект
Основная структура
Promise
— это объект, который в итоге завершится либо успехом, либо ошибкой.
1const promise = new Promise((resolve, reject) => {
2 // Asynchronous operation
3 // Flag indicating whether the operation was successful
4 const success = true;
5
6 if (success) {
7 resolve('Operation successful!');
8 } else {
9 reject('An error occurred');
10 }
11});
- В случае успеха вызывается
resolve()
. - В случае ошибки вызывается
reject()
.
Объект Promise
имеет три состояния.
1promise
2 .then((result) => {
3 console.log(result);
4 })
5 .catch((error) => {
6 console.error(error);
7 })
- Ожидание
- Асинхронный процесс еще не завершён.
- Исполнено
- Асинхронный процесс успешно завершён, результат возвращён с помощью
resolve()
. Результат получен с помощью методаthen()
.
- Асинхронный процесс успешно завершён, результат возвращён с помощью
- Отклонено
- Асинхронный процесс завершился с ошибкой, и возникла ошибка через
reject()
. Ошибка получена с помощью методаcatch()
.
- Асинхронный процесс завершился с ошибкой, и возникла ошибка через
Методы then()
и catch()
С помощью Promise
можно определить, что делать при завершении асинхронной операции. Для этого используются методы then()
и catch()
.
then()
1const promise = new Promise((resolve, reject) => {
2 resolve('Operation successful!');
3});
4
5promise.then((result) => {
6 console.log(result); // "Operation successful!"
7});
- Метод
then()
определяет функцию, которая будет вызвана при успешном выполненииPromise
.
catch()
1const promise = new Promise((resolve, reject) => {
2 reject('An error occurred');
3});
4
5promise.catch((error) => {
6 console.error(error); // "An error occurred"
7});
- Метод
catch()
определяет функцию, которая будет вызвана при сбоеPromise
.
Метод finally()
1const promise = new Promise((resolve, reject) => {
2 resolve('Operation successful!');
3});
4
5promise
6 .then((result) => {
7 console.log(result);
8 })
9 .catch((error) => {
10 console.error(error);
11 })
12 .finally(() => {
13 console.log('The operation has completed');
14 });
- Метод
finally()
определяет код, который будет выполнен в конце, независимо от того, завершился лиPromise
успешно или с ошибкой.
Цепочка then()
then()
возвращает новый объект Promise
, поэтому вы можете сцеплять следующий then()
.
1const promise = new Promise((resolve, reject) => {
2 setTimeout(() => {
3 resolve(1);
4 }, 1000);
5});
6
7promise
8 .then(result => {
9 console.log(result); // 1
10 return result + 1;
11 })
12 .then(result => {
13 console.log(result); // 2
14 return result + 1;
15 })
16 .then(result => {
17 console.log(result); // 3
18 })
19 .catch(error => {
20 console.error(error.message); // Something went wrong
21 });
- В этом коде исходный
resolve()
передает значение 1, и каждое значение, возвращаемое вthen
, передается следующемуthen
. - Используя
catch()
, вы можете обработать любую ошибку, возникшую в цепочке, в одном месте.
Практический пример
Например, Promise
часто используется для получения данных с сервера. Давайте рассмотрим пример с использованием API fetch()
.
1fetch('https://codesparklab.com/json/example.json')
2 .then(response => {
3 if (!response.ok) {
4 throw new Error('Network error');
5 }
6 return response.json();
7 })
8 .then(data => {
9 console.log(data);
10 })
11 .catch(error => {
12 console.error('Error:', error);
13 });
- В этом коде, так как
fetch()
возвращаетPromise
, используетсяthen()
для обработки данных после получения ответа от сервера. Ошибки обрабатываются с помощьюcatch()
.
Обработка нескольких Promises
Promise.all()
Для одновременного выполнения нескольких Promise
и продолжения только в случае их успешного выполнения используйте Promise.all()
.
1const promise1 = Promise.resolve(1);
2const promise2 = Promise.resolve(2);
3const promise3 = Promise.resolve(3);
4
5Promise.all([promise1, promise2, promise3])
6 .then((results) => {
7 console.log(results); // [1, 2, 3]
8 })
9 .catch((error) => {
10 console.error('Error :', error);
11 });
then()
вызывается только в случае успешного выполнения всехPromise
.catch()
вызывается, если хотя бы один изPromise
завершится с ошибкой.
Promise.allSettled()
Если вы хотите запустить несколько промисов одновременно и получить все результаты, независимо от успеха или неудачи, используйте Promise.allSettled()
.
1const promise1 = Promise.resolve(1);
2const promise2 = Promise.reject("Failed");
3const promise3 = Promise.resolve(3);
4
5Promise.allSettled([promise1, promise2, promise3])
6 .then((results) => {
7 results.forEach(result => console.log(result));
8 // [
9 // { status: 'fulfilled', value: 1 },
10 // { status: 'rejected', reason: 'Failed' },
11 // { status: 'fulfilled', value: 3 }
12 // ]
13 });
then()
вызывается, когда все промисы завершились (либо успешно, либо с ошибкой). Каждый результат содержит свойствоstatus
('fulfilled'
или'rejected'
). Даже если некоторые завершаются с ошибкой, это не влияет на другие операции.
Promise.race()
Promise.race()
возвращает результат того Promise
, который завершится первым, независимо от того, был ли он исполнен или отклонён.
1const promise1 = new Promise((resolve) => setTimeout(resolve, 100, 'First'));
2const promise2 = new Promise((resolve) => setTimeout(resolve, 500, 'Second'));
3
4Promise.race([promise1, promise2]).then((result) => {
5 console.log(result); // "First"
6});
- Как и в этом примере, результат первого завершённого
Promise
возвращается.
Связь с async
/await
Использование синтаксиса async
/await
позволяет писать Promise
более интуитивно. async
-функция всегда возвращает Promise
, а await
ожидает её выполнения.
1async function fetchData() {
2 try {
3 const response = await fetch('https://codesparklab.com/json/example.json');
4 const data = await response.json();
5 console.log(data);
6 } catch (error) {
7 console.error('Error :', error);
8 }
9}
10
11fetchData();
Используя async
/await
таким образом, можно записывать асинхронные операции как синхронный код, что делает его проще для чтения.
Резюме
Promise
— это объект для обработки успешного выполнения или ошибки асинхронных операций.- Успешные операции обрабатываются с помощью
then()
, а ошибки — с помощьюcatch()
. finally()
позволяет определить код, который выполняется в конце, независимо от успеха или ошибки.- Вы можете обрабатывать несколько
Promise
одновременно, используяPromise.all()
илиPromise.race()
. async
/await
— это синтаксис для упрощённого написания работы сPromise
.
Вы можете следовать этой статье, используя Visual Studio Code на нашем YouTube-канале. Пожалуйста, также посмотрите наш YouTube-канал.