写源码前,先看Promise是如何使用的,根据使用的方法,大致推出其设计思想,再一步步来实现。
先来看个最简单的Promise:
let promise = new Promise((resolve, reject) => {
let flag = true
if (flag) {
resolve('成功了')
} else {
reject('失败了')
}
})
promise.then(success => {
console.log(success)
}, fail => {
console.log(fail)
})
从上面代码的代码,再结合Promise的基本概念可以看出Promise大概有如下几个特点:
- 需要用new来使用,所以它是一个构造函数,这里用类来实现;
- 在执行这个类的时候,要传递一个执行器进去,执行器会马上执行,执行器里包含两个方法resolve和reject;
- 有三种状态:等待、成功、失败,即一开始为等待状态,然后,要么成功要么失败;
- 状态一旦确定就不可再更改;
- 状态由执行器中的resolve()和reject()来更改,更改的值直接由此方法传入;
- then方法内部判断状态,如果成功就调用成功回调方法返回成功的值,如果失败就调用失败回调方法返回失败的原因。
根据以上6个特点,下面来编码实现。
第一、二步:
class myPromise{
constructor(execute) {
execute(this.resolve,this.reject)
}
resolve = () => {
}
reject = () => {
}
}
如上代码,定义了一个类,构造函数里接收一个执行器并马上执行,执行器中的两个方法resolve和reject也已写好,第一步和第二步已经完成。
第三、四步:
const PENDING = 'pending' // 等待
const RESOLVE = 'resolve' // 成功
const REJECT = 'reject' // 失败
class myPromise {
constructor(execute) {
execute(this.resolve, this.reject)
}
status = PENDING // 状态默认为"等待"
resolve = () => {
// 状态为"等待"才执行,确保状态一旦被确定就不可再被更改
if (this.status === PENDING) {
this.status = RESOLVE
}
}
reject = () => {
// 同resolve中逻辑
if (this.status === PENDING) {
this.status = REJECT
}
}
}
如上代码,新增了"等待"、“成功”、“失败"三种状态,一开始的状态,即默认状态设置为"等待”,随后,要么成功要么失败,由于resolve和reject方法里都做了判断,所以状态被更改后,将无法再被更改,至此,第三、四步已完成。
第五、第六步:
const PENDING = 'pending' // 等待
const RESOLVE = 'resolve' // 成功
const REJECT = 'reject' // 失败
class myPromise {
constructor(execute) {
execute(this.resolve, this.reject)
}
status = PENDING // 状态,默认"等待"
value = undefined // 成功后设置的值,默认undefined
reason = undefined // 失败的原因,默认undefined
resolve = value => {
// 状态为"等待"才执行,确保状态一旦被确定就不可再被更改
if (this.status === PENDING) {
this.status = RESOLVE // 状态设为成功
this.value = value // 存储成功的值
}
}
reject = reason => {
// 同resolve中逻辑
if (this.status === PENDING) {
this.status = REJECT // 状态设为失败
this.reason = reason // 存储失败的原因
}
}
then(successBackcall, failCallback) {
if (this.status === RESOLVE) {
// 如果成功,返回成功的值
successBackcall(this.value)
} else if (this.status === REJECT) {
// 如果失败,返回失败的值
failCallback(this.reason)
}
}
}
上面的代码,添加了三个逻辑:
- 成功时,由resolve设置状态为resolve,存储成功的值;
- 失败时,由reject设置状态为reject,存储成功的值;
- 成功时,在成功回调函数里返回成功的值;失败时,在失败回调函数里返回失败的原因。
至此,Promise的最基础部分的源码已手写完成,接下里将会继续完善剩余部分。
文章内容输出来源:拉勾大前端高薪训练营,以上文章中的内容根据老师讲课的语音和代码,结合自己的理解编辑完成。