promise.finally 适合清理 loading 状态,因为它无论成功或失败都会执行且不接收上一个 promise 的值,避免误改状态;语义清晰、覆盖所有终态,天然适用于只关心“请求是否结束”的场景。

Promise.finally 是清理加载状态的理想选择,因为它无论 Promise 成功还是失败都会执行,且不接收上一个 Promise 的值,避免误改状态或重复赋值。
为什么 finally 适合清理 loading 状态
加载状态(如 isLoading: true)通常只关心“请求是否结束”,不区分成功或失败。用 .then().catch() 分开处理容易遗漏错误分支,或在 catch 中忘记重置;而 .finally() 天然覆盖所有终态,语义清晰、代码更健壮。
基础用法:配合 setState 或响应式变量
常见于 React、Vue 或纯 JS 场景:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- React(函数组件 + useState):
const [loading, setLoading] = useState(false);
const fetchData = async () => {
setLoading(true);
try {
const data = await api.getUser();
setUser(data);
} finally {
setLoading(false); // ✅ 保证执行
}
};
```
- 使用
Promise.finally(兼容 .then 链):
setLoading(true);
fetch('/api/user')
.then(res => res.json())
.then(data => setUser(data))
.catch(err => setError(err.message))
.finally(() => setLoading(false)); // ✅ 不受前面 resolve/reject 影响
```
注意点:finally 不会中断链,也不传参
.finally() 返回的是原 Promise 的延续(不是新 Promise),所以后续 .then() 仍能拿到原始结果;但它本身不接收参数,不能直接读取响应数据或错误 —— 这正是它适合“纯副作用操作”(如关 loading、清 timer、还原按钮)的原因:
- ✅ 正确:关闭 loading、隐藏 skeleton、启用提交按钮
- ❌ 错误:在 finally 里调用
setUser(data)(data 不可访问)、或做条件判断(无输入参数) - ⚠️ 注意:若需在 finally 中访问上下文(如请求 ID),建议闭包捕获或用 async/await 更清晰
进阶:多个请求共用 loading,防竞态
当页面有多个异步操作时,可维护一个计数器,避免单个请求完成就过早关闭 loading:
```jslet pending = 0;
const startLoading = () => {
if (pending++ === 0) setLoading(true);
};
const endLoading = () => {
if (--pending === 0) setLoading(false);
};
// 每次请求
startLoading();
api.getData().finally(endLoading);
api.getProfile().finally(endLoading);
```
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










