摘要:在本教程中,您将学习如何使用 JavaScript Promise finally() 方法在 Promise 解决后执行代码,无论其结果如何。
JavaScript Promise finally() 方法介绍
finally() 方法是 Promise 实例的方法,允许您安排一个函数在 Promise 解决时执行。
以下是调用 finally() 方法的语法
promise.finally(onFinally)Code language: JavaScript (javascript)在此语法中
onFinally是一个函数,当 Promise 解决时异步执行。
finally() 方法返回一个 Promise 对象,允许您方便地将调用链接到 Promise 实例的其他方法。
finally() 方法在 ES2018 中引入。使用 finally() 方法,您可以放置 Promise 解决时清理资源的代码,无论其结果如何。
通过使用 finally() 方法,您可以避免在 then() 和 catch() 方法中出现重复代码,例如
promise
.then(result => {
// process the result
// clean up the resources
})
.catch(error => {
// handle the error
// clean up the resources
});
Code language: JavaScript (javascript)现在,您可以将清理资源部分移动到 finally() 方法中,如下所示
promise
.then(result => {
// process the result
})
.catch(error => {
// handle the error
})
.finally(() => {
// clean up the resources
});
Code language: JavaScript (javascript)finally() 方法类似于 try...catch...finally 语句中的 finally 块。
在同步代码中,您使用 finally 块来清理资源。在异步代码中,您使用 finally() 方法代替。
JavaScript Promise finally() 方法示例
让我们看一些使用 Promise finally() 方法的示例。
1) 使用 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')
}
}
Code language: JavaScript (javascript)Connection 类有两个方法:execute() 和 close()
execute()方法只执行插入、更新或删除查询。如果您传入不在列表中的其他查询,它将发出错误。close()方法关闭连接并清理资源。
以下 connect() 函数返回一个 Promise,如果成功标志设置为 true,则解析为新的 Connection
const success = true;
function connect() {
return new Promise((resolve, reject) => {
if (success)
resolve(new Connection());
else
reject('Could not open the database connection');
});
}
Code language: JavaScript (javascript)以下示例使用 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()`;
}
});
Code language: JavaScript (javascript)在此示例中
connect()函数解析为新的Connection对象,因为success标志设置为true。- 第一个
then()方法执行Insert查询并返回Connection对象。globalConnection用于保存连接。 - 第二个
then()方法执行Select查询并发出错误。catch()方法显示错误消息,finally()方法关闭连接。
2) 使用 Promsie finally() 方法显示加载状态
以下示例展示了如何使用 finally() 方法在调用公共 API https://jsonplaceholder.typicode.com/posts 后隐藏加载元素。
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript finally - API Call with Loading State</title>
<script src="app.js" defer></script>
</head>
<body>
<button id="fetchButton">Fetch Data</button>
<div id="loading" style="display: none">Loading...</div>
<div id="content" style="display: none"></div>
</body>
</html>Code language: JavaScript (javascript)app.js
document.getElementById('fetchButton').addEventListener('click', () => {
const loadingElement = document.getElementById('loading');
const contentElement = document.getElementById('content');
// Show loading and hide content
loadingElement.style.display = 'block';
contentElement.style.display = 'none';
// Make the API call to get posts
fetch('https://jsonplaceholder.typicode.com/posts')
.then((response) => response.json())
.then((posts) => {
// Render the posts
const renderedPosts = posts
.map((post) => {
return `
<h1>${post.title}</h1>
<p>${post.body}</p>
`;
})
.join('');
// Show the posts
contentElement.innerHTML = renderedPosts;
})
.catch((error) => {
// Handle any errors
contentElement.innerHTML = `<p>Failed to load data</p>`;
})
.finally(() => {
// Hide loading and show content
loadingElement.style.display = 'none';
contentElement.style.display = 'block';
});
});
Code language: JavaScript (javascript)工作原理。
document.getElementById('fetchButton').addEventListener('click', () => {
// ...
});Code language: JavaScript (javascript)其次,显示加载元素并隐藏内容元素
const loadingElement = document.getElementById('loading');
const contentElement = document.getElementById('content');
// Show loading and hide content
loadingElement.style.display = 'block';
contentElement.style.display = 'none';Code language: JavaScript (javascript)第三,使用 Fetch API 调用 API 并渲染帖子
fetch('https://jsonplaceholder.typicode.com/posts')
.then((response) => response.json())
.then((posts) => {
// Render the posts
const reenderedPosts = posts
.map((post) => {
return `
<h1>${post.title}</h1>
<p>${post.body}</p>
`;
})
.join('');
// Show the posts
contentElement.innerHTML = reenderedPosts;
})
.catch((error) => {
// Handle any errors
contentElement.innerHTML = `<p>Failed to load data</p>`;
})
.finally(() => {
// Hide loading and show content
loadingElement.style.display = 'none';
contentElement.style.display = 'block';
});Code language: JavaScript (javascript)在 finally() 方法中,隐藏加载元素并显示内容元素。
总结
finally()方法安排一个函数在 Promise 解决时执行,无论成功或失败。- 最佳实践是在 Promise 解决后将清理资源的代码放在
finally()方法中,无论其结果如何。