offline version v3
Запись на курсы по HTML, CSS, JavaScript, PHP, фреймворкам и CMS,
а также: помощь в поиске работы и заказов, стажировка на реальных проектах→
⊗jsSpPrmInr 162 of 294 menu

Введение в промисы в 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 секунд, после которой промис должен выполнится, своим результатом вернув какой-нибудь текст. Выведите этот текст на экран.

enru