promise.finally 用于在 promise 状态最终确定后执行清理逻辑,如关闭加载状态、释放资源等,不接收结果值且不影响链式返回值;适用于需“无论如何都执行”的场景,比重复写在 then 和 catch 中更简洁安全。

Promise.finally 用于在 Promise 状态最终确定(无论 fulfilled 还是 rejected)后执行清理逻辑,比如关闭加载状态、释放资源、重置 UI 等,它不接收 Promise 的结果值,也不影响 Promise 链的返回值。
什么时候该用 finally
当你有一段代码需要「无论如何都执行」,又不想重复写在 .then() 和 .catch() 里时,finally 就是最佳选择。它比手动在两个回调里各写一遍更简洁、更安全。
- 请求结束后隐藏 loading 按钮或 spinner
- 打开的弹窗、遮罩层需要统一关闭
- 临时监听器需要移除(如 abortController.abort())
- 数据库连接或文件句柄需要释放(Node.js 场景)
基本用法和注意事项
finally 接收一个函数,该函数无参数,执行时机在 Promise 完成之后(包括 resolve 或 reject),且不影响链式后续的值传递。
fetch('/api/data')
.then(res => res.json())
.catch(err => console.error('请求失败:', err))
.finally(() => {
// 这里一定会执行,无论成功或失败
loading.value = false;
});
注意:finally 不会捕获错误,如果其内部抛出异常,会以 rejection 形式向下传递;它也不接收上一步的值,所以不能用来做结果处理(那是 then 的职责)。
与 then/catch 组合使用的常见模式
多数时候,finally 和 then/catch 配合使用,分工明确:业务逻辑放 then 和 catch,清理逻辑统一交给 finally。
api.upload(file)
.then(data => {
showMessage('上传成功');
return data;
})
.catch(err => {
showError('上传失败:' + err.message);
})
.finally(() => {
uploadBtn.disabled = false;
progress.value = 0;
});
这样既保证了错误提示和成功反馈的准确性,又避免了清理逻辑遗漏或重复。
在 async/await 中怎么用
finally 是 Promise 方法,不能直接 await,但可以包裹在 Promise 中,或者更推荐的方式是用 try/catch/finally 语句替代:
async function handleUpload() {
uploadBtn.disabled = true;
try {
const data = await api.upload(file);
showMessage('上传成功');
return data;
} catch (err) {
showError('上传失败:' + err.message);
} finally {
// 这里的 finally 和 Promise.finally 行为一致
uploadBtn.disabled = false;
progress.value = 0;
}
}
对于 async 函数,try/catch/finally 更直观、更易读,也支持同步异常;而 Promise.finally 更适合纯 Promise 链式调用场景。










