手写代码的思路为:先从使用开始进行分析。
Promise 的基本使用:
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('ok')
}, 2000)
}).then(res => {
console.log(res) // 'ok'
}, err => {
console.log(err)
})
根据基本使用,再写出注释:
// 1、Promise 为构造函数
// 2、入参为函数,该函数接受两个参数 resolve, reject,该函数是同步运行的
// 3、调用 resolve,则走向成功
// 4、调用 reject,则走向失败
// 5、.then 表明 new Promise 后会返回对象,并且该 then 接受两个参数
// 6、其他情况,它的状态有三个:pending、fulfilled、rejected
function MyPromise(fn) {
// 默认状态
this.state = 'pending'
// Promise 的值,通过 resolve、reject 传入的
this.value = ''
// 保存下 then 方法收到的函数
this.thenSuccessFun = []
this.thenFailFunFun = []
const resolve = (res) => {
this.state = 'fulfilled'
this.value = res
// 当 thenSuccessFun 有长度时,则需要执行里面的方法
if(this.thenSuccessFun.length) {
this.thenSuccessFun.forEach(fn => fn(this.value))
}
}
const reject = (err) => {
this.state = 'rejected'
this.value = err
// 当 thenFailFunFun 有长度时,则需要执行里面的方法
if(this.thenFailFunFun.length) {
this.thenFailFunFun.forEach(fn => fn(this.value))
}
}
// 执行传入的函数
fn(resolve, reject)
// then 方法
this.then = (successFun, failFun) => {
if(this.state === 'pending') {
// 调用 then 时,状态为 pending,表面 fn 里面还未调用 resolve/reject
// 则说明 fn 里面有异步操作,就不能直接调用 successFun/failFun
// 所以需要先存一下
if(typeof successFun === 'function') {
this.thenSuccessFun.push(successFun)
}
if(typeof failFun === 'function') {
this.thenFailFunFun.push(failFun)
}
} else if(this.state === 'fulfilled') {
// 调用 then 时,状态为 fulfilled,表面 fn 里面已调用 resolve
// 则可以直接调用 successFun
if(typeof successFun === 'function') {
successFun(this.value)
}
} else {
// 调用 then 时,状态为 rejected,表面 fn 里面已调用 reject
// 则可以直接调用 failFun
if(typeof failFun === 'function') {
failFun(this.value)
}
}
}
}
// 调试:
new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve('ok')
}, 2000)
}).then(res => {
console.log(res) // 'ok'
}, err => {
console.log(err)
})
// 打印结果:
// ok
上述展示了最基本的使用的实现,但是该实现与源码差的很远,只是让大家入个门,还要考虑各种边界与能力。
其他静态方法的实现原理:
Promise.resolve(anyValue):Promise
: 成功的返回
Promise.resolve = (value) => {
// 当传入值为 Promise 时,直接返回
if(value instanceof Promise) return value
// 返回的还是个 Promise
return new Promise((resolve) => {
resolve(value)
})
}
Promise.reject(anyValue):Promise
: 失败的返回
Promise.reject = (value) => {
// 当传入值为 Promise 时,直接返回
if(value instanceof Promise) return value
// 返回的还是个 Promise
return new Promise((resolve, reject) => {
reject(value)
})
}
Promise.all(Array<Promise>):Promise
: 当所有的 Promise 成功时,则返回成功值的数组,否则返回第一个失败的值
Promise.all = (PromiseArray) => {
// 返回的还是个 Promise
return new Promise((resolve, reject) => {
const result = [] // 存储成功值的数组
// 循环执行 promise,当错误时,直接 reject,当成功时,存储值
PromiseArray.forEach((promise, index) => {
// 最好改为 for 循环,这样可以中断
Promise.resolve(promise).then(res => {
result.push(res)
// 循环执行完毕时,则 resolve(result)
if(result.length - 1 === index) resolve(result)
}).catch(err => {
reject(err)
})
})
})
}
Promise.allSettled(Array<Promise>):Promise
: 当所有的 Promise 执行完时,返回所有结果的数组
Promise.allSettled = (PromiseArray) => {
// 返回的还是个 Promise
return new Promise((resolve, reject) => {
const result = [] // 存储所有值的数组
// 循环执行 promise
PromiseArray.forEach((promise, index) => {
Promise.resolve(promise).then(res => {
result.push({state: 'success', value: res})
// 循环执行完毕时,则 resolve(result)
if(result.length - 1 === index) resolve(result)
}).catch(err => {
result.push({state: 'fali', value: err})
// 循环执行完毕时,则 resolve(result)
if(result.length - 1 === index) resolve(result)
})
})
})
}
Promise.race(Array<Promise>):Promise
: 返回最先执行成功的值
Promise.allSettled = (PromiseArray) => {
// 返回的还是个 Promise
return new Promise((resolve, reject) => {
// 循环执行 promise
PromiseArray.forEach((promise, index) => {
Promise.resolve(promise).then(resolve).catch(reject)
})
})
}