promise 的 finally 方法是清理加载状态的理想位置,因为它无论成功或失败都会执行且不接收结果值;常用于统一恢复按钮状态和隐藏 loading 元素,避免 then/catch 分支遗漏导致 loading 卡住。

Promise 的 finally 方法是清理加载状态(比如关闭 loading 动画、禁用按钮、重置 UI)的理想位置,因为它无论 Promise 成功还是失败都会执行,且不接收 Promise 的结果值。
finally 为什么适合清理加载状态
加载状态通常和异步操作生命周期绑定——只要请求发出去了,就该显示 loading;不管最后成功或出错,loading 都该收掉。而 then/catch 分别只在特定分支执行,容易遗漏错误路径的清理逻辑,导致 loading 卡住。finally 刚好填补这个缺口。
基本写法:配合按钮禁用与 loading 提示
常见场景是点击按钮触发请求,同时禁用按钮并显示 loading。使用 finally 可以统一收尾:
- 把按钮禁用逻辑放在 Promise 开始前
- 在 finally 中恢复按钮状态、隐藏 loading 元素
- 无需在 then 和 catch 里重复写相同的清理代码
示例:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
button.disabled = true;
loadingElement.style.display = 'block';
fetch('/api/data')
.then(res => res.json())
.then(data => console.log('成功:', data))
.catch(err => console.error('失败:', err))
.finally(() => {
button.disabled = false;
loadingElement.style.display = 'none';
});
注意 finally 不会接收参数,也不影响链式结果
finally 回调函数不接收任何参数(既不是 resolve 值,也不是 reject 原因),它只是“执行完就走”。另外,它默认返回上一个 Promise 的结果,不会改变链的值传递行为:
- 如果前面是 resolve(42),finally 执行后仍 resolve(42)
- 如果前面是 reject(new Error('timeout')),finally 执行后仍 reject 同个 error
- 除非你在 finally 里显式 return 一个 Promise 或 throw 错误,否则不会中断或改写链
结合 async/await 时同样适用
即使你用 await 写法,finally 依然有效——只需把整个异步操作包进 try...finally:
button.disabled = true;
loadingElement.style.display = 'block';
try {
const res = await fetch('/api/data');
const data = await res.json();
console.log('成功:', data);
} catch (err) {
console.error('失败:', err);
} finally {
button.disabled = false;
loadingElement.style.display = 'none';
}
这种写法语义更清晰,也更容易控制错误处理粒度。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










