promise 链式调用通过每步返回 promise 保持扁平结构,需避免不返回、返回普通值或内部嵌套 then;统一用 .catch() 处理错误;长链或复杂逻辑推荐 async/await。
promise 的 then 链式调用本身就是为解决回调嵌套而设计的,关键在于“每步返回 promise”和“不手动嵌套”。只要写法得当,就能天然保持扁平结构。
确保每个 then 返回 Promise 或可被自动包装的值
这是维持链条不断开的核心。如果某个 then 回调里没返回东西、返回普通对象、或返回未处理的异步操作(比如忘了 return fetch(...)),后续 then 就收不到预期结果,容易诱使人补一层嵌套来“修复”。
- ✅ 正确:返回
fetch()、Promise.resolve()、其他 Promise 实例,或同步值(会被自动包装) - ❌ 错误:只做 console.log()、DOM 操作却不 return;或在
then里又写new Promise(...)+.then() - 例子:
fetch('/user').then(res => res.json()).then(user => fetch(`/posts?uid=${user.id}`))—— 第二个then明确return了新 Promise,链继续
用 .catch() 统一收口,别在每个 then 里加错误处理
每个 then 的第二个参数(onRejected)只捕获前一个 Promise 的失败,无法覆盖整条链。分散写容易遗漏,也破坏扁平性。
- ✅ 推荐:
.then(...).then(...).catch(err => {...})—— 任一环节 reject 或抛错,都会跳到这个catch - ❌ 不推荐:
.then(..., err => {...}).then(..., err => {...})—— 逻辑割裂,且后一个then的错误不会被前一个err捕获
拒绝“伪链式”:不在 then 内部再写 then
常见误区是把本该链下去的操作,硬塞进当前 then 的回调里,形成视觉上的嵌套:
- ❌ 这样写会退化成回调地狱:
.then(data => { fetch(...).then(...).then(...) }) - ✅ 应该拆出来:
.then(data => fetch(...)).then(res => res.json()).then(posts => ...) - 如果逻辑较重,可封装成独立函数:
.then(getUser).then(fetchOrders).then(render)
必要时用 async/await 替代长链
当链超过 4–5 个 then,或者需要条件分支、循环、复用中间值时,链式反而变僵硬。此时改用 async/await 更自然:
async function loadProfile() { const user = await getUser(); const posts = await getPosts(user.id); return { user, posts }; }- 它本质仍是 Promise 链,但写法更接近同步代码,避免人为嵌套冲动











