参考资料:
核心要点
Promise状态
一个 promise 必须是 3 种状态之一:pending、fulfilled、rejected
pending状态,可以转化成fulfilledrejected状态fulfilled状态,状态不可变,必须有值,该值不可变rejected状态,状态不可变,必须有值,该值不可变
then方法
一个 promise 必须提供 then 方法去获得当前值、fulfilled 或者 rejected 的值。
then 方法接受 2 个参数:
promise.then(onFulfilled, onRejected)
onFulfilled、onRejected均为可选参数- 若
onFulfilled不是函数,必须忽略 - 若
onRejected不是函数,必须忽略
- 若
若
onFulfilled是函数:- promise
fulfilled状态之后必须调用,promise的值作为该函数第1个参数 - promise
fulfilled状态之前禁止调用 - 只能调用一次
- promise
若
onRejected是函数:- promise
rejected状态之后必须调用,promise的值作为该函数第1个参数 - promise
rejected状态之前禁止调用 - 只能调用一次
- promise
在执行上下文栈只包含平台代码之前,
onFulfilled或者onRejected不能被调用onFulfilled和onRejected必须作为函数调用(不能有this)同一个 promise 可以调用多次
then方法- 如果 promise
fulfilled状态,onFulfilled回调必须按照then顺序执行 - 如果 promise
rejected状态,onRejected回调必须按照then顺序执行
- 如果 promise
then方法必须返回一个promise- 如果
onFulfilled或者onRejected返回一个值为 x,执行[[Resolve]](promise2, x) - 如果
onFulfilled或者onRejected抛出错误 e,promise2 必须为rejected - 如果
onFulfilled不是函数,并且 promise1fulfilled状态,promise2 必须fulfilled,并且带有和 promise1 一样的值 - 如果
onRejected不是函数,并且 promise1rejected状态, promise2 必须rejected,并且带有和 promise1 一样的错误信息
- 如果
方法
这 2 个方法接受一个 iterable 类型参数,即 Array,Set,Map
不妨先定义 4 个 Promise
let Promise1 = new Promise(function (resolve, reject) {
setTimeout(() => {
resolve(1)
}, 0)
})
let Promise2 = new Promise(function (resolve, reject) {
setTimeout(() => {
resolve(2)
}, 1000)
})
let Promise3 = new Promise(function (resolve, reject) {
setTimeout(() => {
resolve(3)
}, 3000)
})
let Promise4 = new Promise(function (resolve, reject) {
setTimeout(() => {
reject(4)
}, 1500)
})
const promise_set = new Set();
promise_set.add(Promise1);
promise_set.add(Promise2);
promise_set.add(Promise3);
const iterable = [Promise1, Promise2, Promise3] || promise_set
Promise.all
- 所有都返回执行回调
Promise.all([Promise1, Promise2, Promise3])
.then((value) => {
console.log(value) // [1,2,3] 3000ms后打印
}, (error) => {
console.log(error)
})
- 只要有一个
reject执行立即抛出错误
Promise.all([Promise1, Promise2, Promise4])
.then((value) => {
console.log(value)
}, (error) => {
console.log(error) // 4 1500ms后打印
})
Promise.race
那就是看谁跑的快了
Promise.race([Promise1, Promise2])
.then((value) => {
console.log(value) // 1
}, (error) => {
console.log(error)
})
Promise.race([Promise2, Promise4])
.then((value) => {
console.log(value) // 2
}, (error) => {
console.log(error)
})
Promise.race([Promise3, Promise4])
.then((value) => {
console.log(value)
}, (error) => {
console.log(error) // 4
})
手写Promise
执行逻辑
推荐阅读:V8 Promise源码全面解读 👈
有时候对于多个 then 执行顺序,通过源码的指导会明确很多。
练习
练习1
Promise.resolve()
.then(() => {
console.log(0);
return Promise.resolve(4)
}).then(res => {
console.log(res);
})
Promise.resolve().then(() => {
console.log(1);
}).then(() => {
console.log(2);
}).then(() => {
console.log(3);
}).then(() => {
console.log(5);
}).then(() => {
console.log(6);
})