Skip to content

Promise 怎么工作? ​

Promise 是状态机:pending 只能变成 fulfilled 或 rejected,而且只变一次。then 每次都返回一个新的 Promise,所以能链式调用。出错会沿链向后传,直到 catch 或带失败回调的 then。

原理 ​

执行器里的 resolve 把状态变成成功,reject 或抛错变成失败。resolve 的如果是另一个 thenable,当前 Promise 会跟它的结果走,而不是直接成功。

then 的回调放进微任务。回调的返回值成为下一个 Promise 的成功值;返回 thenable 就继续等它;抛错则下一个 Promise 失败。

js
Promise.resolve(1)
  .then((value) => value + 1)
  .then(() => {
    throw new Error("x")
  })
  .catch((err) => {
    console.log(err.message) // x
    return 0
  })
  .then((value) => console.log(value)) // 0

常用的静态方法:

  • Promise.all:全部成功才成功,一个失败就失败。
  • Promise.allSettled:全部结束才结束,逐个给出成功或失败。
  • Promise.race:谁先落定用谁的结果。
  • Promise.any:谁先成功用谁;全部失败才失败,原因是 AggregateError。

追问 ​

它比回调多解决了什么?

成功和失败变成可以组合的值,错误能沿链传递,避免一层层嵌套。它不负责取消。取消请求用 AbortController。

async/await 怎样才会并行?

连续写两个 await 是串行,第二个要等第一个完成才开始。要并行,先把 Promise 创建出来,再 await Promise.all([a, b])。

then 里面没有 return 会怎样?

下一环拿到 undefined,链还在,只是值丢了。

易错点 ​

  • 状态不可逆。先 reject 再 resolve 时,后面的调用被忽略。
  • 忘记处理 rejection,浏览器会报未处理的 Promise 拒绝。await 放在 try/catch 里,或者链尾加 catch。
  • Promise.resolve().then(...) 不是同步执行。

相关 ​