# Введение в промисы в JavaScript

Вы уже знаете, что использование коллбэк-модели асинхронности легко приводит к ситуации callback hell. Поэтому в JavaScript была введена новая модель под названием промисы (англ. promise, обещание). Давайте изучим эту модель.

Промис представляет собой объект, в который параметром передается функция, внутри которой нужно размещать наш асинхронный код:

`let promise = new Promise(function() { // асинхронный код });`

Как вы видите, я записал объект с промисом в переменную `promise`. В каком-то другом месте кода я могу применить к этой переменной метод `then`, передав в него функцию с кодом, который должен быть выполнен по завершении асинхронного кода, написанного при создании данного промиса:

`promise.then(function() { // выполнится при завершении асинхронного кода });`

Звучит запутано, поэтому давайте посмотрим на примере. Пусть у меня есть вот такой асинхронный код:

`setTimeout(function() { let result = [1, 2, 3, 4, 5]; }, 3000);`

Пусть я хочу решить для него нашу основную задачу асинхронности: выполнить некоторый код после срабатывания таймера. При этом я не хочу размещать этот код в самом таймере и хочу, чтобы в этот код как-то попал результат, написанный мною в переменной `result`. В общем-то, мы решали эту задачу в предыдущих уроках через коллбэки и подписки. Давайте теперь посмотрим, как это сделать через промисы.

Для начала нужно обернуть наш асинхронный код в промис:

`let promise = new Promise(function() { setTimeout(function() { let result = [1, 2, 3, 4, 5]; }, 3000); });`

Этого, однако, не достаточно. Мы должны в явном виде указать, что наш асинхронный код завершился. В этом нам поможет специальная функция завершения, автоматически попадающая в первый параметр функции, если он указан:

`let promise = new Promise(function(resolve) { // указываем параметр setTimeout(function() { let result = [1, 2, 3, 4, 5]; }, 3000); });`

С помощью функции завершения мы можем явно указать промису, что асинхронный код завершился. Для этого мы должны вызвать эту функцию в нужном нам месте:

`let promise = new Promise(function(resolve) { setTimeout(function() { let result = [1, 2, 3, 4, 5]; resolve(); // завершаем промис }, 3000); });`

При этом, если мы хотим передать вовне какой-то результат асинхронного кода, мы можем передать его параметром нашей функции завершения:

`let promise = new Promise(function(resolve) { setTimeout(function() { let result = [1, 2, 3, 4, 5]; resolve(result); // передаем результат }, 3000); });`

Можно, конечно же, избавится от промежуточной переменной:

`let promise = new Promise(function(resolve) { setTimeout(function() { resolve([1, 2, 3, 4, 5]); }, 3000); });`

Теперь в любом другом месте мы можем вызвать метод `then` нашего промиса:

`promise.then(function() { // сработает по завершению промиса });`

Результат работы промиса попадет в первый параметр функции, если мы пожелаем его указать:

`promise.then(function(result) { console.log(result); // выведет массив с результатом });`

Сделайте промис, внутри которого будет задержка в `5` секунд, после которой промис должен выполнится, своим результатом вернув какой-нибудь текст. Выведите этот текст на экран.

←→
↑
en ru