Промисы в JavaScript простым языком

от автора

Эта статья содержит простое объяснение, как работать с промисами, с краткими примерами кода. Если вы уже использовали промисы в JavaScript, вряд ли вы узнаете что-то новое — прим. перев.

JavaScript — это синхронный язык программирования, но благодаря колбэкам мы можем заставить его работать асинхронно. Вместе с колбэками приходит «Ад обратных вызовов». Промисы изобрели, чтобы писать асинхронные программы без него.

Промисы

Промисы (от английского Promise — обещание) очень похожи на обещания из реальной жизни.

  • После того, как обещание сделано, мы получаем обязательство выполнения «чего-то» в будущем и можем строить дальнейшие планы, исходя из этого
  • Как и в реальной жизни, обещания могут быть сдержаны или нарушены
  • Обещания не готовы мгновенно, мы можем работать с их результатами только после того, как обещания сдержаны

В JavaScript: «Объект Promise (промис) используется для отложенных и асинхронных вычислений».

Создание промисов

Создание объектов происходит по такому шаблону:

new Promise(function(resolve, reject) { ... });

Выполняющая функция (executor) принимает два аргумента resolve и reject, которые являются колбэками. Промисы используются для обработки асинхронных операций, являющихся блокирующим кодом. Обращения к БД, I/O или API — всё это примеры таких операций, с которыми должна разобраться выполняющая функция. Как только она завершится, она либо исполнит промис (вызовет resolve), либо отклонит его (вызовет reject).

Простой пример:

let promise = new Promise(function(resolve, reject) {  if(promise_kept) {   resolve("done"); } else {   reject(new Error("…"));   }  });

Как видно, Promise не возвращает значение сразу. Он ждёт завершения блокирующей операции и вызывает подходящий колбэк. Это позволяет асинхронным методам возвращать значения, как если бы они были синхронными. Просто вместо возвращения значения (которого пока нет) возвращается промис.

Очевидно, что у промиса могут быть разные состояния:

  1. ожидание (pending): начальное состояние, не исполнен и не отклонен
  2. исполнено (fulfilled): операция завершена успешно
  3. отклонено (rejected): операция завершена с ошибкой

Пример:

Использование промисов

С созданием промисов проблем быть не должно, так что давайте перейдём к их использованию:

const isDone = new Promise() //...  const checkIfDone = () => {   isDone     .then(ok => {       console.log(ok)     })     .catch(err => {       console.error(error)     }) }

Вызов .checkIfDone() начнёт исполнение промиса isDone и дождётся его завершения, вызвав колбэк для результата. В случае ошибки будет вызван метод .catch().

Цепочка промисов

Методы промиса .then() и .catch() сами возвращают промис, для которого можно вновь вызвать .then() или .catch(), создав таким образом цепочку из промисов:

new Promise(function(resolve, reject) {    setTimeout(() => resolve(1), 1000);   }).then(function(result) {     alert(result);    return result * 3;  }).then(function(result) {     alert(result);    return result * 4;  }).then(function(result) {    alert(result);    return result * 6;  });

В коде выше каждый промис передаёт результат своего исполнения в следующий .then() и так до полного завершения всей цепочки.

Заключение

Промисы, а точнее цепочки из них, позволяют нам контролировать порядок выполнения асинхронных операций в коде без ада обратных вывозов. В следующей статье мы разберём способ сделать асинхронный код ещё чище и понятнее.


ссылка на оригинал статьи https://habr.com/ru/post/480522/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *