Промисы в JavaScript простым языком
- вторник, 17 декабря 2019 г. в 00:34:17
Эта статья содержит простое объяснение, как работать с промисами, с краткими примерами кода. Если вы уже использовали промисы в 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 не возвращает значение сразу. Он ждёт завершения блокирующей операции и вызывает подходящий колбэк. Это позволяет асинхронным методам возвращать значения, как если бы они были синхронными. Просто вместо возвращения значения (которого пока нет) возвращается промис.
Очевидно, что у промиса могут быть разные состояния:
Пример:
С созданием промисов проблем быть не должно, так что давайте перейдём к их использованию:
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() и так до полного завершения всей цепочки.
Промисы, а точнее цепочки из них, позволяют нам контролировать порядок выполнения асинхронных операций в коде без ада обратных вывозов. В следующей статье мы разберём способ сделать асинхронный код ещё чище и понятнее.