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