talk is cheap, show me the code
const Pendding = Symbol('Pendding')
const Fulfilled = Symbol('Fulfilled')
const Rejected = Symbol('Rejected')
class Promise {
status = Pendding
value = undefined
reason = undefined
resQueue = []
rejQueue = []
constructor(fn) {
try {
fn(this.resolve.bind(this), this.reject.bind(this))
} catch (e) {
this.reject(e)
}
}
resolve(value) {
if (this.status !== Pendding) return
this.status = Fulfilled
this.value = value
while (this.resQueue) this.resQueue.shift()(value)
}
reject(reason) {
if (this.status !== Pendding) return
this.status = Rejected
this.reason = reason
while (this.rejQueue) this.rejQueue.shift()(reason)
}
then(resCb, rejCb) {
let _this = this
let promise2 = new Promise((resolve, reject) => {
let resCbTask = (value) => {
try {
resCb(value) // 本次回调
resolve(value) // 传递值给下一个promise
} catch (e) {
reject(e)
}
}
let rejCbTask = (reason) => {
try {
rejCb(reason)
reject(reason)
} catch (e) {
reject(e)
}
}
// 上一个resolve或reject是异步调用
if (_this.status === Pendding) {
_this.resQueue.push(queueMicrotask(resCbTask)) // 微任务
_this.rejQueue.push(queueMicrotask(rejCbTask))
return
}
// 上一个reject是同步调用
if (_this.status === Rejected) {
queueMicrotask(()=> rejCbTask(_this.reason)) // 微任务
return
}
// 上一个resolve是同步调用
if (_this.status === Fulfilled) {
queueMicroTask(()=>resCbTask(_this.value)) // 微任务
}
})
return promise2
}
static resolve(value) {
// 开启微任务
queueMicrotask(() => new Promise((resolve) => resolve(value)))
}
static reject(reason) {
queueMicrotask(() => new Promise((reject) => reject(reason)))
}
// 返回所有resolve的promise,否则reject
static all(promises) {
// 所有promise resolve后返回结果数组,非promise直接resolve
// 若有一个reject直接reject
return new Promise((resolve, reject) => {
let ret = []
let n = 0
function handle(res, i) {
ret[i] = res
n++
if (n === promises.length) resolve(ret)
}
promises.forEach((promise, idx) => {
if (!promise instanceof Promise) return handle(promise, idx)
promise.then(res => handle(res, idx), e => reject(e))
})
})
}
// 返回第一个resolve的promise,若有一个reject立刻reject
static race(promises) {
return new Promise((resolve, reject) => {
for (let promise of promises) {
if (!promise instanceof Promise) return resolve(promise)
promise.then(res => resolve(res), e => reject(e))
}
})
}
// 返回所有promise,无论结果是resolve还是reject
static allSettled(promises) {
return new Promise((resolve, _) => {
let ret = []
let n = 0
function handle(promise, i, status) {
ret[i] = { status, value: promise }
n++
if (n === promises.length) resolve(ret)
}
promises.forEach((promise, idx) => {
if (!promise instanceof Promise) return handle(promise, idx, 'fulfilled')
promise.then(res => handle(res, idx, 'fulfiiled'), e => handle(e, idx, 'rejected'))
})
})
}
// 和race唯一的区别是有reject先跳过,争取找到任何一个可以resolve的promise
static any(promises) {
return new Promise((resolve, reject) => {
let rejects = []
let count = 0
for (let promise of promises) {
if (!promise instanceof Promise) return resolve(promise)
promise.then(
(res) => resolve(res),
(e) => {
rejects.push(e)
count++
if (count === promises.length) reject(rejects) // 全部GG
}
)
}
})
}
}