外观
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(...)不是同步执行。