Промисы

Раздел:

МетодыАргументыВозвращаетОписание
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
   
})();