Promise根本原因是回调无法可靠表达异步的三种状态和链式依赖;它通过统一状态流转契约解决嵌套、错误传播、并发协调等问题,但需正确返回和处理才能发挥效力。

JavaScript 需要 Promise 对象,根本原因不是为了“更酷”或“更现代”,而是因为**回调函数无法可靠地表达异步操作的三种状态(待定、成功、失败)和链式依赖关系**——尤其在多个异步步骤嵌套、需要统一错误处理、或需并行协调时,回调会迅速失控。
回调地狱让错误传播和流程控制彻底失效
当你写 fs.readFile 套 fetch 再套 setTimeout,每个回调都得手动检查 err、手动传递结果、手动决定下一步——一旦中间某步出错,后续回调可能照常执行,或者整个链静默失败。
实操建议:
- 避免在回调里直接写业务逻辑,尤其不要多层嵌套;
- 哪怕只有一层异步,也优先用
Promise包装(例如new Promise((resolve, reject) => { ... })); -
Promise的.catch()会自动捕获前面所有.then()中抛出的异常和 rejected 状态,而回调没有这种穿透能力。
Promise.then() 的返回值决定下一级状态
很多人以为 .then() 只是“接着做”,其实它的返回值直接控制链路走向:
立即学习“Java免费学习笔记(深入)”;
本文档主要讲述的是j2me3D游戏开发简单教程; 如今,3D图形几乎是任何一部游戏的关键部分,甚至一些应用程序也通过用3D形式来描述信息而获得了成功。如前文中所述,以立即模式和手工编码建立所有的3D对象的方式进行开发速度很慢且很复杂。应用程序中多边形的所有角点必须在数组中独立编码。在JSR 184中,这称为立即模式。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
- 返回一个普通值 → 下个
.then()的onFulfilled接收该值; - 返回一个
Promise→ 下个.then()等待它 settle 后再执行; - 抛出异常或返回
Promise.reject(...)→ 下个.then()跳过,由最近的.catch()或.then(null, onRejected)处理。
这使得“异步转同步写法”成为可能,但前提是每一步都正确返回 Promise。漏掉 return 是最常见错误,会导致下一级立即拿到 undefined 并继续执行。
Promise.all() 和 Promise.race() 解决并发协调问题
原生回调没有标准方式表达“等全部完成”或“取最快响应”。你得自己计数、标记、判断完成条件——容易出竞态、漏错误、难调试。
实操注意点:
-
Promise.all([p1, p2, p3])在任意一个被 reject 时立刻 reject,不等其余; - 若需“全部执行完,不管成败”,改用
Promise.allSettled()(ES2020+); -
Promise.race()不是“选最快成功”,而是“选最先 settle(无论 fulfill/reject)”,常被误用于超时控制——必须配合Promise.reject()手动构造超时拒绝,否则失败会被吞掉。
真正难的不是写 Promise,而是理解它不改变异步本质,只是提供一套可组合、可推导、可预测的状态流转契约。很多 bug 来自把 Promise 当同步用,或在未 resolve 的地方提前 return,或混淆 async/await 和 Promise 的错误边界——这些细节比语法本身更影响线上稳定性。










