实现一个Promise
Promise是异步请求的一种解决方案,不同于传统的回调函数,它通过链式调用很好的解决了回调地狱,让异步执行清晰明了。在实际开发中也经常使用Promise,那Promise内部是如何实现的呢?
我们通过Promise的使用方式为突破口,实现一个Promise,为了与Promise区分,我们实现的Promise称它为MyPromise。
// Promise使用
let promise = new Promise((resolve, reject) => {
// TODO
// fulfilled => resolve(value)
// rejected => reject(reason)
})
上面是创建Promise实例最常用的写法,通过使用Promise,我们知道它有3个状态:pending、fulfilled、rejected,且状态只能由pending转变为fulfilled或pending转变为rejected,转变之后不能再变化,如:pending转变成fulfilled之后不能再变成rejected,也就是Promise状态变化不可逆。
我们通过new关键词生成一个Promise实例,可以看出Promise会接收一个函数(我们暂时称它为executor函数)作为参数,Promise实例生成后executor函数会被调用,也就是该函数内的代码被执行,executor函数接收resolve和reject两个参数,当Promise状态从pending转变成fulfilled时,会调用resolve函数,并传入状态变为fulfilled后的返回值value作为参数;当状态变成rejected时,调用reject函数,并传入状态变为rejected后的返回值reason作为参数。
通过上述分析,我们可以将MyPromise写成如下:
// MyPromise的三种状态
let PENDING = 'pending'
let FULFILLED = 'fulfilled'
let REJECTED = 'rejected'
function MyPromise(executor) {
let that = this
that.status = PENDING // 初始状态
that.value = undefined // 状态变成fulfilled后resolve的值
that.reason = undefined // 状态变成rejected后reject的原因
// 定义executor函数的参数resolve
function resolve(value) {
// TODO
if(that.status === PENDING){
that.status = FULFILLED
that.value = value
}
}
// 定义executor函数的参数reject
function reject(reason) {
// TODO
if(that.status === PENDING){
that.status = REJECTED
that.reason = reason
}
}
// 执行executor函数
try{
executor(resolve, reject)
} catch(e) {
reject(e)
}
}
上面我们搭建了MyPromise的基本框架,继续分析Promise的使用来完善MyPromise
// Promise使用
// 状态为fulfilled的Promise实例
let promise = new Promise((resolve, reject) => {
resolve(1)
})
// Promise实例具有then方法
let promise1 = promise.then((res) => {
console.log(res)
return res
}, (e) => {
console.log(e)
})
// 1
// Promise实例调用then方法后也返回一个Promise实例,且与之前的实例不同
promise1.then((res) => {
console.log(res)
})
// 1
promise === promise1
// false
// Promise实例then方法具有值穿透的功能
promise.then().then((res) => {
console.log(res)
})
// 1
// 状态为rejected的Promise实例
let promise2 = new Promise((resolve, reject) => {
reject(2)
})
let promise3 = promise2.then((res) => {
console.log(res)
}, (e) => {
console.log(e)
})
// 2
上面可以看出:1、Promise实例调用then方法后返回一个新的Promise实例,与之前的实例不是同一个东西;2、当then方法中参数为空时,then方法具有值穿透的功能;3、Promise实例都有then方法,then方法可以接收两个参数(我们暂时称它们分别为onFulfilled、onRejected),当Promise实例状态为fulfilled时,调用其then方法会执行onFulfilled函数,状态为rejected时,调用onRejected函数,当Promise实例状态为pending时,会将onFulfilled和onRejected函数分别添加到onFulfilledCallback和onRejectedCallback数组中,等待Promise实例状态转变,然后执行其对应的回调;
functon MyPromise(executor) {
...
that.onFulfilledCallback = [] // 存放当前状态为pending,状态如果转变为fulfilled时执行的回调onFulfilled
that.onRejectedCallback = [] // 存放当前状态为pending,状态如果转变为rejected时执行的回调onRejected
function resolve(value) {
if(that.status === PENDING){
...
that.onFulfilledCallback.forEach(</