В этом руководстве вы узнаете, как использовать метод JavaScript Promise finally()
для выполнения кода после того, как обещание выполнено, независимо от его результата.
Предположим, что у вас есть промис:
promise .then(result => { ...}) .catch(error => { ... }) .finally(() => { ... })
Метод finally()
всегда выполняется независимо от того, выполнено обещание или отклонено. Другими словами, метод выполняется, когда обещание выполнено.
Метод finally()
был представлен в ES2018. В метод вы можете поместить код, который очищает ресурс, когда обещание выполнено, независимо от его результата. Используя метод finally()
, вы можете избежать дублирования кода в методах then()
и catch()
следующим образом:
promise .then(result => { // process the result // clean up the resources }) .catch(error => { // handle the error // clean up the resources });
Теперь вы можете переместить часть очистки ресурсов в метод finally()
следующим образом:
promise .then(result => { // process the result }) .catch(error => { // handle the error }) .finally(() => { // clean up the resources });
Метод finally()
подобен блоку finally
в операторе try...catch...finally
. В синхронном коде вы используете блок для очистки ресурсов. Вместо этого в асинхронном коде вы используете метод finally()
.
Пример
Следующий пример определяет класс Connection
:
class Connection { execute(query) { if (query != 'Insert' && query != 'Update' && query != 'Delete') { throw new Error(`The ${query} is not supported`); } console.log(`Execute the ${query}`); return this; } close() { console.log('Close the connection') } }
Класс Connection
имеет два метода: execute()
и close()
:
- Метод
execute()
будет выполнять только запросы на вставку, обновление или удаление. Это выдаст ошибку, если вы перейдете к другому запросу, которого нет в списке. - Метод
close()
закрывает соединение, как бы очищая ресурс.
Следующая функция connect()
возвращает обещание, которое преобразуется в новое Connection
, если для флага успеха установлено значение true:
const success = true; function connect() { return new Promise((resolve, reject) => { if (success) resolve(new Connection()); else reject('Could not open the database connection'); }); }
В следующем примере используется метод finally()
для закрытия соединения:
let globalConnection; connect() .then((connection) => { globalConnection = connection; return globalConnection.execute('Insert'); }) .then((connection) => { globalConnection = connection; return connection.execute('Select'); }) .catch(console.log) .finally(() => { if (globalConnection) { globalConnection.`close()`; } });
В этом примере:
- Функция
connect()
преобразуется в новый объектConnection
, поскольку для флагаsuccess
установлено значениеtrue
. - Первый метод
then()
выполняет запросInsert
и возвращает объектConnection
.globalConnection
используется для сохранения соединения. - Второй метод
then()
выполняет запросSelect
и выдает ошибку. Методcatch()
показывает сообщение об ошибке, а методfinally()
закрывает соединение.
Заключение
- Метод
finally()
назначает функцию для выполнения, когда обещание либо выполнено, либо отклонено. - Хорошей практикой является размещение кода, который очищает ресурсы, в методе
finally()
после того, как обещание выполнено, независимо от его результата.