Promise.finally()用于无论成功或失败都执行的清理操作,不接收参数、不影响Promise状态,常用于关闭加载状态、恢复UI等;错误未捕获会冒泡,finally中抛错会覆盖原结果。

Promise.finally() 专门用于处理“无论成功还是失败都要执行”的逻辑,比如关闭加载状态、释放资源、重置 UI 等。它不接收参数,也不影响 Promise 的最终状态或返回值,只关心执行时机。
finally 的基本用法
在 Promise 链末尾调用 finally(),传入一个函数,该函数会在 Promise 被 fulfilled 或 rejected 后立即执行:
- 它不接收任何参数(既不是 resolve 值,也不是 reject 原因)
- 它不会改变 Promise 的链式结果:上一个 then/catch 的返回值会继续向下传递
- 如果 finally 中抛出错误,会以该错误替代原 Promise 的结果(除非被后续 catch 捕获)
常见清理场景示例
比如发起请求时显示 loading,无论成功或失败都要隐藏:
showLoading();
fetch('/api/data')
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error('请求失败:', err))
.finally(() => hideLoading()); // ✅ 自动执行,无需重复写两遍
再比如操作 DOM 元素后恢复初始状态:
- 点击按钮禁用,请求结束后统一启用(不管成功失败)
- 打开模态框后,请求完成自动关闭(避免遗漏 reject 分支)
- 启动定时器后,在 Promise 结束时 clearTimeout
注意 finally 和 then/catch 的区别
finally 不是“兜底 catch”,它不捕获错误,也不处理响应数据:
- 想处理错误?仍需用 catch()
- 想读取成功数据?仍在 then() 里做
- finally 只做“收尾动作”,比如清理副作用
错误若未被捕获,仍会向上冒泡;finally 中的错误会覆盖原 Promise 的状态——所以清理逻辑尽量保持简单、避免 throw。
与 async/await 配合使用
在 async 函数中,finally 同样适用,但更推荐用 try/finally 语法,语义更清晰:
async function loadData() {
showLoading();
try {
const res = await fetch('/api/data');
const data = await res.json();
return data;
} catch (err) {
console.error(err);
} finally {
hideLoading(); // ✅ 更直观,且能确保执行
}
}
不过 Promise 链中仍可混用:promise.then(...).catch(...).finally(...) 完全合法且常用。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











