promise源码

73 阅读2分钟

基本原理

> 1.promise是一个类,在执行这个类的时候接收一个执行器,这个执行器会立即执行
> 2.promise会有三种状态(等待,成功,失败)
> 3.状态只能由等待->成功,或者是等待->失败,一旦改变不可更改
> 4.resolve,reject来改变状态

//promise有三种状态
//等待 成功 失败
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';

class myPromise {
    constructor(executor) {
        //在执行器运行要捕获错误
        try {
            executor(this.resolve, this.reject)

        } catch (error) {
            this.reject(error)
        }
    }
    //初始状态
    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()(this.value)
    }
    //失败函数
    reject = (reason) => {
        //改变状态为失败
        if (this.status !== PENDING) return
        this.status = REJECTED;
        this.reason = reason;
        //判断有没有,有就执行一个删除一个
        while (this.failCallback.length) this.failCallback.shift()(this.reason)
    }
    //原型上的then方法
    then(successCallback, failCallback) {
        //判断参数是否存在
        successCallback = successCallback ? successCallback : value => value
        failCallback = failCallback ? failCallback : reason => { throw reason }
        //链式调用时,上一个then的返回值会作为下一个then的参数。下一个then调用,上一个then需返回promise
        let promise2 = new myPromise((resolve, reject) => {

            if (this.status === FULFILLED) {
                //添加settimeout,为了可以拿到Promise2
                setTimeout(() => {
                    //在then中要捕获错误,抛出错误
                    try {
                        //拿到上一个的返回值
                        let x = successCallback(this.value)
                        //判断x的值,为普通值,直接调用
                        //为promise对象,再判断状态,进行不同操作。
                        resolvePromise(promise2, x, resolve, reject)
                    } catch (error) {
                        reject(error)
                    }

                }, 0)


            } else if (this.status === REJECTED) {

                //添加settimeout,为了可以拿到Promise2
                setTimeout(() => {
                    //在then中要捕获错误,抛出错误
                    try {
                        //拿到上一个的返回值
                        let x = failCallback(this.reason)
                        //判断x的值,为普通值,直接调用
                        //为promise对象,再判断状态,进行不同操作。
                        resolvePromise(promise2, x, resolve, reject)
                    } catch (error) {
                        reject(error)
                    }

                }, 0)
            } else {
                //多次调用的话,就放进一个数组
                this.successCallback.push(() => {
                    setTimeout(() => {
                        //在then中要捕获错误,抛出错误
                        try {
                            //拿到上一个的返回值
                            let x = successCallback(this.value)
                            //判断x的值,为普通值,直接调用
                            //为promise对象,再判断状态,进行不同操作。
                            resolvePromise(promise2, x, resolve, reject)
                        } catch (error) {
                            reject(error)
                        }

                    }, 0)
                });
                this.failCallback.push(() => {
                    setTimeout(() => {
                        //在then中要捕获错误,抛出错误
                        try {
                            //拿到上一个的返回值
                            let x = failCallback(this.reason)
                            //判断x的值,为普通值,直接调用
                            //为promise对象,再判断状态,进行不同操作。
                            resolvePromise(promise2, x, resolve, reject)
                        } catch (error) {
                            reject(error)
                        }

                    }, 0)
                });
            }
        })

        return promise2
    }
    //catch
    catch(failCallback){
        return this.then(undefined,failCallback)
    }
    //all方法,作为静态方法
    static all(array) {
        //定义一个数组 index用于处理异步
        let result = [];
        let index = 0;
        return new myPromise((resolve, reject) => {

            //往数组添加元素 函数
            function addData(key, value) {
                result[key] = value;
                //往数组添加一个,这个index就+1
                index++
                //判断index和array的长度相等的时候再执行resolve
                if (index === array.length) {
                    resolve(result)
                }
            }
            for (let i = 0; i < array.length; i++) {
                if (array[i] instanceof myPromise) {
                    array[i].then(value => addData(i, value), reason => reject(reason))
                } else {
                    addData(i, array[i])
                }
            }
        })
    }
     //静态方法 resolve
    static resolve(value) {
        if (value instanceof myPromise) return value
        return new myPromise(resolve => resolve(value))
    }
}

function resolvePromise(promise2, x, resolve, reject) {
    if (promise2 === x) {
        reject(new TypeError('nasnajsnajsnajnsjanjsan'))
    }
    if (x instanceof myPromise) {
        x.then(resolve, reject)
    } else {
        resolve(x)
    }
}
module.exports = myPromise