promise链式调用通过将嵌套回调转为扁平.then()序列,每个异步操作返回新promise以自然承接结果;.then()可返回值、普通数据或promise,分别决定下个.then()的参数;错误统一由.catch()处理,支持中间校验、转换与错误恢复,需避免不return、混用回调及误串行并发请求。

用 Promise 链式调用替代回调地狱,核心是把嵌套的回调函数转成扁平的 .then() 序列,每个异步操作返回一个新的 Promise,让后续逻辑自然承接上一步的结果。
Promise 链式调用的基本结构
每个 .then() 接收上一个 Promise 的成功结果,并可返回新值或新 Promise。若返回 Promise,下一个 .then() 会等待它完成后再执行。
- 不返回值 → 下一个
.then()的参数为undefined - 返回普通值(如字符串、对象)→ 下一个
.then()直接接收该值 - 返回 Promise → 下一个
.then()等待它 resolve 后再执行,接收其 resolved 值
从回调地狱到 Promise 链的改写示例
假设依次请求用户信息、订单列表、订单详情:
// 回调地狱(嵌套深、难维护)
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
getUser(userId, function(user) {
getOrders(user.id, function(orders) {
getOrderDetail(orders[0].id, function(detail) {
console.log(detail);
});
});
});
// 改为 Promise 链(扁平、可读性强)
getUser(userId)
.then(user => getOrders(user.id))
.then(orders => getOrderDetail(orders[0].id))
.then(detail => console.log(detail))
.catch(err => console.error('出错了:', err));
关键点:每个函数都需返回 Promise(如用 fetch 或封装过的 Promise 版本),且错误统一由最后的 .catch() 处理。
链中处理错误和中间逻辑
链式调用中可灵活插入转换、校验、合并等同步操作,也能在任意环节捕获异常:
- 用
.then()做数据预处理(如过滤、格式化) - 用
.catch()捕获当前及之前所有未处理的 reject - 若想“吞掉”某个错误并继续链路,可在
.catch()中返回默认值或新 Promise
例如:
fetchUser()
.then(user => {
if (!user.active) throw new Error('用户已停用');
return user;
})
.then(user => fetchPosts(user.id))
.catch(err => {
console.warn('获取 posts 失败,使用空数组', err);
return []; // 继续链路,下一个 then 接收 []
})
.then(posts => render(posts));
注意避免常见陷阱
-
忘记 return Promise:在
.then()里调用了异步函数但没 return,会导致下一个.then()立即执行(拿到undefined) -
混用回调和 Promise:比如在
.then()里又写setTimeout(..., callback),破坏链式流 -
多个并发请求误写成串行:需并发时用
Promise.all([p1, p2, p3]),而非链式调用










