Автор заметки, перевод которой мы сегодня публикуем, говорит, что с трудом удержался от того, чтобы не назвать её «Finally — возможность, которую все ждали», или как-то пошутить на эту тему. В итоге он решил обойтись без шуток и просто рассказать о по-настоящему важной и полезной возможности объектов Promise.
Если вы только начинаете осваивать 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 до появления его стандартных реализаций?
Автор: ru_vds