Promise源码解析

95 阅读3分钟

Promise源码解析

  1. Promise就是一个类 在执行这个类的时候需要传递一个执行器进去,执行器会立即执行\
  2. Promise中有三种状态:成功(fulfilled)、失败(rejected)和等待(pending),一旦状态确定就不能改,状态只能从等待变为成功或者变为失败\
  3. resolve和reject函数是用来更改状态的\
  4. then方法内部做的事情就是判断状态,如果状态是成功 调用成功的回调函数。then方法是被定义在原型对象中的\
  5. then成功回调有一个参数 表示成功之后的值,失败回调参数表示失败的原因\
  6. then方法可以被多次调用\
  7. then方法是可以被链式调用的,后面then方法的回调函数拿到的值是上一个then方法的回调函数的返回值\
  8. then方法的参数是可选参数
```const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

class MyPromise {
    constructor (executor) {
        try {
            executor(this.resolve, this.reject)
        } catch (e) {
            this.reject(e)
        }
    }
    status = PENDING
    // 成功之后的值
    value = undefined
	  // 失败之后的原因
	  reason = undefined
	  // 成功回调
	  successCallback = []
	  // 失败回调
	  failCallback = []
    resolve = value => {
        // 如果状态不是等待 阻止程序向下执行
        if(this.status !== PENDING) return
        this.status = FULFILLED
        this.value = value
        // 判断成功回调是否存在 如果存在就调用
        while(this.successCallback.length){
             this.successCallback.shift()()
      	}
    }
    reject = reason => {
        // 如果状态不是等待 阻止程序向下执行
        if(this.status !== PENDING) return
        this.status = REJECTED
        this.reason = reason
        // 判断失败回调是否存在 如果存在就调用
        while(this.failCallback.length){
             this.failCallback.shift()()
      	}
    }
    then (successCallback, failCallback) {
        // 如果不传参数或者传递的不是函数 那就补充一个函数
      	if(Object.prototype.toString.call(successCallback) !== "[object Function]"){
        	successCallback = value => value
        }
      	if(Object.prototype.toString.call(failCallback) !== "[object Function]"){
        	failCallback = reason => { throw reason }
        }
        let promise2 = new MyPromise((resolve,reject) => {
            if(this.status === FULFILLED) {
                queueMicrotask(()=> {
                    try{
                         // 上一个then的成功回调返回值
                       let x = successCallback(this.value)
                       // 判断 x 的值是普通值还是promise对象
                       // 如果是普通值,直接调用resolve
                       // 如果是promise对象 查看promise对象返回的结果
                       // 再根据promise对象返回的结果 决定调用resolve 还是调用reject
                       resolvePromise(promise2,x,resolve,reject)
                    }catch (e) {
                        reject(e)
                    }
                })
            } else if(this.status === REJECTED) {
                queueMicrotask(()=> {
                    try{
                         // 上一个then的成功回调返回值
                       let x = failCallback(this.reason)
                       // 判断 x 的值是普通值还是promise对象
                       // 如果是普通值,直接调用resolve
                       // 如果是promise对象 查看promise对象返回的结果
                       // 再根据promise对象返回的结果 决定调用resolve 还是调用reject
                       resolvePromise(promise2,x,resolve,reject)
                    }catch (e) {
                        reject(e)
                    }
                })
            } else {
                // 等待
                // 将成功回调和失败回调存储起来
                this.successCallback.push(()=> {
                    queueMicrotask(()=> {
                        try{
                             // 上一个then的成功回调返回值
                           let x = successCallback(this.value)
                           // 判断 x 的值是普通值还是promise对象
                           // 如果是普通值,直接调用resolve
                           // 如果是promise对象 查看promise对象返回的结果
                           // 再根据promise对象返回的结果 决定调用resolve 还是调用reject
                           resolvePromise(promise2,x,resolve,reject)
                        }catch (e) {
                            reject(e)
                        }
                    })
                })
                this.failCallback.push(() => {
                    queueMicrotask(()=> {
                        try{
                             // 上一个then的成功回调返回值
                           let x = failCallback(this.reason)
                           // 判断 x 的值是普通值还是promise对象
                           // 如果是普通值,直接调用resolve
                           // 如果是promise对象 查看promise对象返回的结果
                           // 再根据promise对象返回的结果 决定调用resolve 还是调用reject
                           resolvePromise(promise2,x,resolve,reject)
                        }catch (e) {
                            reject(e)
                        }
                    })
                })
            }
        })
        return promise2
    }
}

function resolvePromise(promise2, x, resolve, reject){
    if(promise2 === x) {
        return reject(new TypeError(""))
    }
    if(x instanceof MyPromise) {
        // promise对象
        x.then(resolve, reject)
    } else {
        // 普通值
        resolve(x)
    }
}

```js