Что такое Promise в JS


Promise появились в стандарте ES6. В стандарте ES5 функциональность промисов уже можно было использовать, только вынесена она была в отдельные библиотеки. Теперь же промисы официально добавлены в стандарт и если вы все еще не работали с промисами и не знаете что это такое, самое время в этом разобраться. Предистория Любой код написанный на JavaScript выполняется синхронно (последовательно сверху вниз). Однако после того, как скрипты стали усложняться и для того чтобы не блокировать дальнейшее выполнение программы, стал активнее использоваться асинхронный код. Для того чтобы задать последовательность для асинхронных операций, придумали промисы. До появления промисов для этой задачи использовали коллбэки. Однако из-за возникновения больших вложенностей у этих callback функций, написание кода превратилось в ад. Возникла острая потребность в более элегантном синтаксисе, так и появились Promise. Объект Promise (обещание) позволяет более удобно работать с асинхронным кодом. В синхронном коде, строки кода выполняются одна за другой. В асинхронном коде, дело обстоит немного иначе. Например у нас есть изображение, но нужно, чтобы оно загрузилось не одновременно с веб-страничкой, а при нажатии на кнопку. Синхронный код Что произойдет в синхронном коде, когда пользователь нажмет на кнопку? Браузер полностью заблокируется и не будет реагировать на другие действия пользователя. Все то время пока изображение грузится, пользователь не сможет делать что-то еще на сайте. Асинхронный код В асинхронном коде не блокируются какие-то другие действия пользователя. Можно спокойно выполнять такие операции, которые требуют некоторого ожидания, отложенности во времени, и в то же время, не тормозя другие процессы на странице. Работа с Promise В обычном программировании, когда все строки кода выполняются последовательно и без ожидания завершения какой-то загрузки, Promise совершенно не нужен. Он применяется в достаточно сложных вещах, что-то вроде технологии AJAX. Сейчас рассмотрим на абстрактном примере принципы работы Promise - опишем функцию setTimeout(), которая будет имитировать выполнение длительного ожидания. Мы создаем новое обещание, в котором обещаем, что картинка будет загружена и когда картинка загрузится, то мы что-нибудь сделаем. Запишем объект класса Promise в переменную promise. Стрелочная функция принимает два параметра: resolve, reject. В эти параметры скрипт сам положит функции result и error. Промис может иметь только два состояния: успешное выполнение задачи (resolve) или неуспешное (reject). Например ваша картинка может загрузится успешно, а может из-за какой-нибудь ошибки и вовсе не загрузиться. Суть промиса в следующем: у вас есть какая-то функция. Внутри этой функции, должен выполнится код нужной вам операции (загрузка картинки). Как только картинка будет загружена, вызывается функция result. При неудачной загрузки - error. При успешном выполнении функции, вызывается resolve, при неуспешном вызывается reject. Мы даем обещание, что имитация загрузки картинки будет происходить 3 секунды. Просто на это время запустим таймер. Загрузка картинки, не помешает выполнению другого кода на странице или действиям пользователя. Так сказать картинка будет подгружаться в фоновом режиме, никому не мешая. let promise = new Promise((resolve, reject) => { // создание обещания setTimeout(() =>{ let test = false; // неудачная загрузка картинки if (test) { resolve('result'); } else { reject('error'); } }, 3000); }); promise.then( result => {alert(result)}, error => {alert(error)} // при неудачи выведется алерт с ошибкой ); console.log('!'); Наш промис случится через 3 секунды. На переменной promise вызываем метод then. Этот метод должен принять две функции. Функция result сработает, если промис выполнился успешно. Функция error сработает, если промис выполнился не успешно. Итак, мы создали promise, функция пошла выполняться и когда она выполнится (момент выполнения это вызов resolve или reject). Промис никогда не выполнится, если мы не одну из них не вызвали. Затем сработает одна из двух функций.