Promise是解决回调地狱的核心方案,通过链式then调用替代嵌套回调,支持错误统一捕获、并行(all)与竞速(race)组合,并需注意返回值和catch的正确使用。

ES6 的 Promise 是解决“回调地狱”的核心方案,它用链式调用替代多层嵌套回调,让异步逻辑更线性、可读、可维护。
Promise 基本写法:把回调转成 then 链
传统回调嵌套(回调地狱)示例:
getData(function(a) {
getMoreData(a, function(b) {
getEvenMoreData(b, function(c) {
console.log(c);
});
});
});
用 Promise 改写后:
getData() .then(a => getMoreData(a)) .then(b => getEvenMoreData(b)) .then(c => console.log(c)) .catch(err => console.error(err));
关键点:
立即学习“Java免费学习笔记(深入)”;
- 每个异步函数需返回一个 Promise(如用 new Promise 封装或直接返回已有的 Promise)
- then 方法接收上一个 Promise 的成功结果,并可返回新 Promise,实现自动链式传递
- 错误统一由 catch 捕获,无需每层写 error 回调
封装回调 API 为 Promise
很多老接口(如 Node.js 的 fs.readFile、浏览器的 XMLHttpRequest)仍用回调风格,需手动 Promise 化:
function readFileAsync(file) {
return new Promise((resolve, reject) => {
fs.readFile(file, 'utf8', (err, data) => {
if (err) reject(err);
else resolve(data);
});
});
}
之后就能自然链式调用:
readFileAsync('a.txt')
.then(data => readFileAsync('b.txt'))
.then(data => console.log(data))
.catch(e => console.error('出错了'));
并行与串行:合理组合多个异步任务
多个异步操作不总是串行。Promise 提供了灵活组合方式:
- Promise.all([]):所有任务并行执行,全部成功才 resolve,任一失败则整体 reject
- Promise.race([]):返回最先完成(无论成功/失败)的那个 Promise 的结果
- 需要串行但依赖前序结果时,坚持用 .then() 链;无依赖且想提速,优先用 all
例如同时请求用户和订单数据:
Promise.all([
fetch('/api/user'),
fetch('/api/order')
])
.then(([userRes, orderRes]) => Promise.all([
userRes.json(),
orderRes.json()
]))
.then(([user, order]) => renderPage(user, order))
.catch(err => showError(err));
注意陷阱:避免忘记 return 或漏写 catch
常见错误会导致链中断或错误静默:
- 在 then 回调中忘记 return 新 Promise → 下一个 then 接收到 undefined
- 只在末尾写 catch → 它只能捕获前面链中抛出的错误;若中间某 then 内部出错但没被处理,会跳过后续 then 直到 catch
- 混用回调和 Promise(比如在 then 里又写 callback)→ 失去 Promise 的优势,可能引发未捕获异常
推荐写法:每个 then 明确返回值,末尾必接 catch,复杂逻辑可拆成小函数提升可读性。


















