[Перевод] ES2018 — метод промисов finally

Автор заметки, перевод которой мы сегодня публикуем, говорит, что с трудом удержался от того, чтобы не назвать её «Finally — возможность, которую все ждали», или как-то пошутить на эту тему. В итоге он решил обойтись без шуток и просто рассказать о по-настоящему важной и полезной возможности объектов Promise.

vxwec2slp-mndo8ep4anvgcykgg.png


Если вы только начинаете осваивать JavaScript и не слишком хорошо знакомы с промисами (иногда их называют «обещаниями», «обещанными результатами», «Promise-объектами»), то, возможно, вам будут интересны наши предыдущие публикации на эту тему:

→ Промисы в ES6: паттерны и анти-паттерны
→ JavaScript: методы асинхронного программирования
→ JavaScript ES8 и переход на async / await
→ Async/await: 6 причин забыть о промисах
→ Побег из ада async/await
→ JavaScript ES6: пишем меньше — делаем больше
→ Руководство по промисам для тех, кто хочет в них разобраться
→ Конструкция async/await в JavaScript: сильные стороны, подводные камни и особенности использования
→ Использование промисов в JavaScript

Метод Promise.prototype.finally


Методу Promise.prototype.finally посвящён пункт 25.6.5.3 стандарта ECMAScript 2018. По информации ресурса caniuse.com, уровень поддержки этого метода составляет примерно 81%. Этим методом можно пользоваться и в среде Node.js.

Метод промисов finally — это одно из важнейших новшеств стандарта, которое позволяет задавать функцию, которая будет выполнена независимо от результата промиса. Такая функция выполнится и при успешном разрешении промиса и при его отклонении.
Рассмотрим пример:

const myPromise = new Promise((resolve, reject) => {

 setTimeout(() => { resolve('success!!!'); }, 2000);

});


Это — совершенно обычный промис, который разрешается через 2000 миллисекунд. Если после этого нужно выполнить какое-то действие — нам понадобится блок then:

myPromise.then(

 result => { console.log(result) },

 failMessage => { console.log(failMessage) }

);


Методу then переданы две анонимных функции. Первая будет выполнена в том случае, если промис будет успешно разрешён. Вторая — при его отклонении. Наш промис всегда завершает работу успешно, в консоль всегда будет выводиться сообщение success!!!. Всё это очень хорошо, но как быть, если надо, чтобы некие действия выполнялись бы и после отклонения промиса, и после успешного завершения его работы? Тут нам и поможет метод finally:

const myPromise = new Promise((resolve, reject) => {

 setTimeout(() => { resolve('success!!!'); }, 2000);

});


myPromise.then(

 result => { console.log(result) },

 failMessage => { console.log(failMessage) }

).finally(finallyMessage => { console.log('FINALLY!!')});


Независимо от того, как промис завершит работу, в консоль, помимо соответствующего сообщения, будет выведен текст FINALLY!!, что говорит нам о том, что функция обратного вызова, переданная методу finally, срабатывает в любом случае. Для того чтобы в этом убедиться — можете поэкспериментировать.

Итоги


То, что в ES2018 появился метод Promise.prototype.finally, говорит о том, что в обозримом будущем можно ожидать очень высокого уровня его поддержки браузерами. Это значит, что то, для чего раньше приходилось использовать вспомогательные инструменты, созданные сторонними разработчиками, теперь может быть реализовано стандартными средствами.

В каких ситуациях может пригодиться метод Promise.prototype.finally? Например — если при запуске промиса, используемого для загрузки чего-либо, начинает воспроизводиться некая анимация, в finally можно завершить эту анимацию. В блоке finally можно, например, закрыть некое модальное окно. На самом деле, существует множество ситуаций, в которых метод finally может оказаться полезным.

Уважаемые читатели! Пользовались ли вы заменителями метода промисов finally до появления его стандартных реализаций?

1ba550d25e8846ce8805de564da6aa63.png

© Habrahabr.ru