Promise链式调用通过每个.then()返回新Promise实现线性流程,避免回调地狱;顺序依赖用链式,无依赖用Promise.all()并行;.catch()统一错误处理,可局部容错;封装API、抽离逻辑、注意return提升健壮性。

用 Promise 链式调用告别回调地狱,核心就一条:把每个异步操作包装成返回 Promise 的函数,然后用 .then() 串起来,用 .catch() 统一捕获错误——不再嵌套,逻辑线性清晰。
Promise 链的基本写法
每个 .then() 接收上一个 Promise 的成功结果,并返回一个新的 Promise(可以是显式 new Promise(),也可以是直接返回值或另一个 Promise)。这样就能自然“往下传”数据,避免层层缩进:
- 返回普通值 → 下一个
.then()收到该值 - 返回 Promise → 下一个
.then()等它 resolve 后再执行 - 抛出错误或返回被 reject 的 Promise → 跳转到最近的
.catch()
例如:
fetch('/api/user').then(res => res.json())
.then(user => fetch(`/api/posts?uid=${user.id}`))
.then(res => res.json())
.then(posts => console.log(posts))
.catch(err => console.error('出错了:', err));
处理异步依赖关系:顺序 vs 并行
链式调用天然适合「前一步结果是后一步输入」的顺序依赖。如果多个请求彼此独立,别硬塞进链里,改用 Promise.all() 并行发起,更高效:
- 顺序链:适合 A→B→C(B 需要 A 的结果,C 需要 B 的结果)
-
Promise.all([p1, p2, p3]):适合 A、B、C 无依赖,一起发,等全部完成 - 混合使用:比如先取用户,再并行查用户订单 + 用户评论
示例:
使用约定式提交(Conventional Commits)生成标准化的 Git 提交信息。适用于以下场景: (1) 暂存更改时需要提交信息; (2) 审查 diff 时希望获得结构化摘要; (3) 编写 PR 描述或变更日志(changelog)条目; (4) 用户明确要求“为本次更改编写提交信息”。 该功能会分析已暂存/未暂存的 diff,并生成按类型(type)划分范围的提交信息。
.then(res => res.json())
.then(user =>
Promise.all([
fetch(`/api/orders?uid=${user.id}`).then(r => r.json()),
fetch(`/api/comments?uid=${user.id}`).then(r => r.json())
])
)
.then(([orders, comments]) => {
console.log({ orders, comments });
});
错误处理必须加 .catch(),且位置很关键
链中任意环节出错(包括 throw、Promise reject、JSON 解析失败等),都会跳过后续所有 .then(),直达最近的 .catch()。所以:
- 不要在每个
.then()里自己 try/catch 异步逻辑 -
.catch()放在链末尾,就能捕获整条链的错误 - 如果想“局部消化”某个错误(比如 404 时返回默认数据),可在对应
.then()后接.catch(),再返回替代值,让链继续
例如容错写法:
fetch('/api/config').then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
.catch(() => ({ theme: 'light', lang: 'zh' })) // 出错就用默认配置
.then(config => renderApp(config));
实际项目中的小技巧
让 Promise 链更健壮、易读:
- 封装常用 API 调用为返回 Promise 的函数,比如
getJSON(url),内部处理 status 和 json 解析 - 避免在
.then()回调里写大量同步逻辑,可抽成独立函数,提升可读性 - 需要中途“暂停”?用
await(配合 async 函数)比手动写setTimeout+ Promise 更直观——但本质仍是 Promise 链的语法糖 - 注意:不要在链中间漏掉
return,否则下一个.then()会收到undefined










