Промисы
Раздел:
Методы | Аргументы | Возвращает | Описание |
new Promise() | функция с двумя callback аргументами: 1) resolve 2) reject | промис | выполняет асинхронный код и по его завершении вызывает resolve или reject. |
then() | 1) onFulfill — функция-колбэк 2) onReject — функция-колбэк | промис | метод будет вызван после изменения состояния промиса |
catch() | onReject — функция-колбэк | промис | отрабатывает, когда вызывается reject() внутри промиса |
finally() | Функция-колбэк без параметров | промис | вызовет функцию по завершении промиса вне зависимости от состояния |
Promise.any() | массив промисов | промис | выполняет несколько промисов параллельно и дожидается первого успешно разрешённого |
Promise.all() | массив промисов | промис | вызывает функцию, когда будет завершён самый медленный промис |
Promise.allSettled() | массив промисов | промис | ждёт выполнения всех промисов, при этом неважно, завершились они успешно или с ошибкой |
Promise.race() | массив промисов | промис | вернёт результат, когда будет завершён самый быстрый промис, остальных дожидаться не будет |
♦ new Promise()
new Promise( (resolve, reject) => { ... } )
Внутри промиса работает асинхронная операция, которая управляет его состоянием. Принимает функцию, возвращает промис.
Callback функция может принимать следующие аргументы:
- функция resolve, которая принимает любой тип данных как результат успешного выполнения
- функция reject, которая принимает любой тип данных как сообщение об ошибке выполнения.
new Promise( (resolve, reject) => {
setTimeout(() => { resolve('received data') }, 2000);
}).then( (text)=> {
console.log(text); // "received data"
})
♦ then
promise.then( (result) =>{ ... }, (error) => { ... } )
Метод будет вызван после изменения состояния промиса.
принимает два аргумента:
- onFulfill — функция-колбэк, которая будет вызвана при переходе промиса в состояние fulfilled, функция имеет один параметр, в который передаётся результат выполнения операции
- onReject — функция-колбэк, которая будет вызвана при переходе промиса в состояние rejected, функция имеет один параметр, в который передаётся информация об ошибке
new Promise( (resolve, reject) => {
setTimeout( () => {
const random = Math.random() * (10 - 5) + 5;
if( random > 7 ){
resolve('received data');
} else {
reject(new Error('operation execution error'));
}
}, 1000);
}).then(
(text)=> {
// эта функция не будет вызвана в случае reject
console.log(text); // "received data"
},
(error)=> {
// эта функция не будет вызвана в случае resolve
console.log(error); // "operation execution error"
}
)
♦ catch
catch( (error) => { ... } )
Отрабатывает, когда вызывается reject() внутри промиса.
принимает один аргумент:
- onReject — функция-колбэк, которая будет вызвана при переходе промиса в состояние rejected, функция имеет один параметр, в который передаётся информация об ошибке.
new Promise( (resolve, reject) => {
setTimeout( () => {
reject(new Error('operation execution error'));
}, 1000);
}).then( (text)=> {
// эта функция не будет вызвана
console.log(text);
}).catch(
(error)=> {
console.log(error); // "operation execution error"
}
)
♦ finally
finally( () => { ... } )
Вызовет функцию по завершению промиса вне зависимости от состояния. Функция-колбэк параметры не принимает. Такой метод удобно использовать, когда мы включаем лоадер для пользователя, при вызвове функции-колбэка можно лоадер отключить.
new Promise( (resolve, reject) => {
setTimeout( () => {
reject(new Error('operation execution error'));
}, 1000);
}).then( (text)=> {
// эта функция не будет вызвана
console.log(text);
}).catch(
(error)=> {
console.log(error); // "operation execution error"
}
).finally( () => {
// будет вызвана при любом изменении промиса
console.log('the finish'); // "the finish"
})
♦ Promise.any()
Promise.any( [promis1, promis2, promis3] )
Выполняет несколько промисов параллельно и дожидается первого успешно разрешённого. Не выдаст ошибки, если будет ошибка на одном из промисов. Ошибка будет, если все промисы завершатся с ошибкой.
const dataOne = new Promise(resolve => setTimeout(() => resolve(1), 4000));
const dataTwo = new Promise(resolve => setTimeout(() => resolve(2), 2000));
let dataThree = new Promise(resolve => setTimeout(() => resolve(3), 1000));
Promise.any([dataOne, dataTwo, dataThree])
.then((value) => {
console.log(value); // 3
});
dataThree = new Promise((resolve, reject) => setTimeout(() => reject(3), 1000));
Promise.any([dataOne, dataTwo, dataThree])
.then((value) => {
console.log(value); // 2
});
♦ Promise.all
Promise.all( [promis1, promis2, promis3] )
Получает маccив промисов и вызывает функцию, когда будет завершён самый медленный промис. Возвращает массив результатов завершённых промисов. Если хотя бы один промис завершился с ошибкой, то выполнение остальных промисов остановится и будет возвращена ошибка.
const dataOne = new Promise(resolve => setTimeout(() => resolve(1), 4000));
const dataTwo = new Promise(resolve => setTimeout(() => resolve(2), 2000));
const dataThree = new Promise(resolve => setTimeout(() => resolve(3), 1000));
Promise.all([dataOne, dataTwo, dataThree])
.then(([dataOne, dataTwo, dataThree]) => {
// результат получим через 4 сек.
console.log(dataOne); // 1
console.log(dataTwo); // 2
console.log(dataThree); // 3
});
♦ Promise.allSettled()
Promise.allSettled( [promis1, promis2, promis3] )
Ждёт выполнения всех промисов, при этом неважно, завершились они успешно или с ошибкой. Возвращает массив результатов, которые являются объектами. Объект состоит из двух свойств status и value, но последнее в случае ошибки может быть заменено на reason.
- status — сообщает, корректно выполнился промис или нет
- value — если промис был выполнен корректно, то в этом свойстве будет его результат
- reason — если промис завершился с ошибкой то это свойство вернёт данные об ошибке
const dataOne = new Promise(resolve => setTimeout(() => resolve(1), 4000));
const dataTwo = new Promise(resolve => setTimeout(() => resolve(2), 2000));
const dataThree = new Promise((resolve, reject) => setTimeout(() => reject(3), 1000));
Promise.allSettled([dataOne, dataTwo, dataThree])
.then(([dataOne, dataTwo, dataThree]) => {
// результат получим через 4 сек.
console.log(dataOne); // { status: "fulfilled", value: 1 }
console.log(dataTwo); // { status: "fulfilled", value: 2 }
console.log(dataThree); // { status: "rejected", reason: 3 }
});
♦ Promise.race()
Promise.race( [promis1, promis2, promis3] )
Вернёт результат когда будет завершён самый быстрый промис, остальных дожидаться не будет. Если самый быстрый промис завершится с ошибкой, то будет передана ошибка и остальные не будут выполнены. Если передать в Promise.race([]) пустой список, то промис навсегда зависнет в состоянии pending.
const dataOne = new Promise(resolve => setTimeout(() => resolve(1), 4000));
const dataTwo = new Promise(resolve => setTimeout(() => resolve(2), 2000));
let dataThree = new Promise((resolve, reject) => setTimeout(() => reject(3), 1000));
Promise.race([dataOne, dataTwo, dataThree])
.then(([dataOne, dataTwo, dataThree]) => {
// then не будет вызван
}).catch((error)=>{
// результат получим через 1 сек.
console.log(error); // 3
});
dataThree = new Promise(resolve => setTimeout(() => resolve(3), 3000));
Promise.race([dataOne, dataTwo, dataThree])
.then((value) => {
console.log(value); // 2
}).catch((error)=>{
// catch не будет вызван
});
Дополнительно
♦ async | await
async () => await Promise
async делает функцию асинхронной а await позволяет дожидаться завершения промиса. Асинхронная функция возвращает промис.
( async () => {
const dataOne = await new Promise(resolve => setTimeout(() => resolve(1), 4000));
const dataTwo = await new Promise(resolve => setTimeout(() => resolve(2), 2000));
try {
const dataThree = await new Promise((resolve, reject) => setTimeout(() => reject(3), 1000));
} catch {
console.log('ошибка');
}
// общее время ожидание составило: 7 сек
console.log(dataOne); // 1
console.log(dataTwo); // 2
})();