Промисы — важная функция современного JavaScript, которая позволяет разработчикам обрабатывать асинхронные операции более эффективным и удобочитаемым способом. В этом блоге мы углубимся в мир промисов и рассмотрим некоторые передовые методы работы с ними в JavaScript.
Что такое обещания?
Промисы — это объекты в JavaScript, которые представляют возможное завершение или сбой асинхронной операции и позволяют вам обрабатывать результат этой операции, когда он будет готов. Обещания имеют три состояния:
- Ожидание: начальное состояние промиса при его создании.
- Выполнено: состояние обещания при успешном завершении асинхронной операции.
- Отклонено: состояние обещания при сбое асинхронной операции.
Промисы позволяют объединять асинхронные операции и обрабатывать ошибки более организованным способом, чем обратные вызовы.
Вот пример того, как создать и использовать промис в JavaScript:
const myPromise = new Promise((resolve, reject) => { setTimeout(() => { const randomValue = Math.random(); if (randomValue > 0.5) { resolve(randomValue); } else { reject(new Error('Random value is too low!')); } }, 1000); }); myPromise.then((result) => { console.log(`Promise was fulfilled with result: ${result}`); }).catch((error) => { console.error(`Promise was rejected with error: ${error}`); });
В этом примере мы создаем новый объект Promise, который принимает функцию в качестве аргумента. Функция получает два параметра, resolve
и reject
, которые являются функциями, которые можно использовать для выполнения или отклонения обещания после завершения асинхронной операции.
В этом случае мы используем setTimeout
для имитации асинхронной операции, выполнение которой занимает одну секунду. Мы генерируем случайное число, и если оно больше 0,5, мы выполняем обещание с этим значением. В противном случае мы отклоняем обещание с объектом ошибки.
Затем мы используем метод then
для обработки выполнения обещания, записывая результат в консоль. Если обещание отклонено, мы обрабатываем ошибку с помощью метода catch
.
Цепочка обещаний
Обещания также могут быть объединены в цепочку для выполнения ряда асинхронных операций. Это можно сделать, вернув новый Promise из метода then
.
Вот пример того, как связать промисы в JavaScript:
const myPromise = new Promise((resolve, reject) => { setTimeout(() => { resolve(10); }, 1000); }); myPromise.then((result) => { console.log(`First result: ${result}`); return result * 2; }).then((result) => { console.log(`Second result: ${result}`); return result - 4; }).then((result) => { console.log(`Third result: ${result}`); }).catch((error) => { console.error(`Promise was rejected with error: ${error}`); });
В этом примере мы создаем новое обещание, которое выполняется через одну секунду со значением 10
. Затем мы используем метод then
, чтобы выполнить три операции над этим значением: удвоить его, вычесть 4 и записать окончательный результат в консоль.
Если какой-либо из методов then
выдает ошибку, будет вызван метод catch
с объектом ошибки.
Продвинутые методы обещаний
Есть несколько более продвинутых методов, которые вы можете использовать с промисами для обработки более сложных сценариев в JavaScript.
Обещание.гонка
Метод Promise.race
похож на Promise.all
, но вместо ожидания завершения всех промисов он ожидает выполнения или отклонения первого промиса. Метод принимает массив обещаний в качестве аргумента и возвращает новое обещание, которое выполняется с результатом первого выполненного обещания.
const promises = [ new Promise((resolve) => setTimeout(() => resolve(1), 1000)), new Promise((resolve) => setTimeout(() => resolve(2), 500)), new Promise((resolve) => setTimeout(() => resolve(3), 2000)), ]; Promise.race(promises).then((result) => { console.log(`The first promise to complete returned ${result}`); });
В этом примере мы создаем массив из трех обещаний, каждое из которых выполняется через разное время. Затем мы используем Promise.race
, чтобы дождаться завершения первого промиса и записать его результат в консоль.
Обещание.все
Метод Promise.all
принимает в качестве аргумента массив обещаний и возвращает новое обещание, которое выполняется с массивом результатов, когда все входные обещания выполнены, или отклоняет с указанием причины отклонения первого обещания.
const promises = [ new Promise((resolve) => setTimeout(() => resolve(1), 1000)), new Promise((resolve) => setTimeout(() => resolve(2), 2000)), new Promise((resolve) => setTimeout(() => resolve(3), 3000)), ]; Promise.all(promises).then((values) => { console.log(`All promises resolved: ${values}`); });
В этом примере мы создаем массив из трех обещаний, каждое из которых выполняется через разное время. Затем мы используем Promise.all
, чтобы дождаться завершения всех промисов и записать их результаты в консоль.
Обещание.любое
Метод Promise.any
похож на Promise.race
, но вместо ожидания выполнения первого обещания он ожидает выполнения первого обещания. Если все промисы отклонены, метод выдает AggregateError
, содержащий все причины отклонения.
const promises = [ new Promise((resolve) => setTimeout(() => resolve(1), 1000)), new Promise((resolve, reject) => setTimeout(() => reject(new Error('Failed')), 500)), new Promise((resolve) => setTimeout(() => resolve(3), 2000)), ]; Promise.any(promises).then((result) => { console.log(`The first promise to fulfill returned ${result}`); }).catch((error) => { console.error(`All promises were rejected: ${error}`); });
В этом примере мы создаем массив из трех обещаний, одно из которых отклонено. Затем мы используем Promise.any
, чтобы дождаться выполнения первого обещания и записать его результат в консоль. Если все обещания отклонены, мы перехватываем ошибку и записываем сообщение в консоль.
Заключение
Промисы — это важная функция современного JavaScript, позволяющая обрабатывать асинхронные операции более эффективно и читабельно. Их можно использовать для цепочки асинхронных операций, параллельного выполнения нескольких промисов и более организованной обработки ошибок.
Поняв эти передовые методы работы с промисами, вы сможете вывести свой асинхронный код JavaScript на новый уровень и написать более эффективный, удобочитаемый и удобный для сопровождения код.