finally回调返回Promise不改变原Promise终态,但会延迟后续链式调用执行;若返回被reject的Promise,则覆盖原结果并使链进入rejected分支。

finally 回调中返回 Promise,不会改变当前 Promise 的终态,但会延迟后续链式调用的执行时机。它不“接管”状态(即不会把 fulfilled 变成 rejected,也不会把 rejected 变成 fulfilled),但会让 .then() 或 .catch() 的执行,等到这个返回的 Promise settle(即变为 fulfilled 或 rejected)之后才继续。
finally 本身不改变状态,但返回值会影响链条节奏
无论原始 Promise 是 fulfilled 还是 rejected,.finally() 总会执行;它的回调函数若返回一个 Promise,整个链式流程会暂停,等待该 Promise 完成,再将原始结果(或错误)向下传递。
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 原始 Promise 成功 →
finally返回 Promise → 等待它 resolve 后,继续走下一个.then(),传入原始成功值 - 原始 Promise 失败 →
finally返回 Promise → 等待它 resolve 后,继续走下一个.catch()(或未捕获时抛出),传入原始错误 - 如果
finally返回的 Promise 被 reject,则该 rejection 会“覆盖”原始结果,导致后续链直接进入 rejected 分支
常见写法与实际效果对比
假设有一个请求 Promise:
const req = fetch('/api/data').then(r => r.json());-
req.finally(() => console.log('清理')):无返回值 → 下一个.then()立即执行 -
req.finally(() => delay(500)):返回 Promise → 下一个.then()在 500ms 后才执行,但依然拿到原始响应数据 -
req.finally(() => Promise.reject(new Error('cleanup failed'))):返回被 reject 的 Promise → 后续.then()被跳过,直接进.catch(),错误是 cleanup 的错误,不是原始请求错误
为什么容易误判?关键在“不透传 rejection”
.finally() 的设计初衷是做清理(如关闭 loading、释放资源),它默认忽略自己的返回值类型——但一旦返回的是 Promise,JS 引擎就必须等它 settle,这是规范强制行为。而它对 rejection 的处理不像 .then() 那样有明确的“错误转换”逻辑,所以 返回被 reject 的 Promise 就等于中断原链并注入新错误。
- 安全做法:在
finally中只做同步操作,或确保返回的 Promise 必然 resolve - 需要异步清理又不想影响主链?用
.then(() => cleanup(), () => cleanup())替代,或把 cleanup 放到.finally(() => cleanup().catch(() => {}))
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










