Promsie js实现

step 1

初始化promise对象:

const PENDING = 'pending';const FULFILLED = 'fulfilled';const REJECTED = 'rejected';class MPromise {    /**     *      * @param {Function} fn (resolve, reject)    */    constructor(fn){        // 初始状态为pending        this.status = PENDING;        this.value = null;        this.reason = null;    }        resolve(value){    }    reject(resaon){    }}

step 2

实现resolve 和 reject办法

    /**     *      * @param {Function} fn (resolve, reject)    */    constructor(fn){        // 初始状态为pending        this.status = PENDING;        this.value = null;        this.reason = null;        try{            fn(this.resolve.bind(this), this.reject.bind(this));    // 为什么须要 bind(this) ?             // 传入的fn可能是一个一般的函数,并不是箭头函数,有他本人的执行环境        }catch(e){            this.reject(e);        }    }        resolve(value){        // 判断状态  只有PENDING才能够批改状态        if(this.status === PENDING){            this.value = value;            this.status = FULFILLED;        }    }    reject(resaon){        // 判断状态  只有PENDING才能够批改状态        if(this.status === PENDING){            this.resaon = resaon;            this.status = REJECTED;        }    }

step 3

then办法的实现

    then(onFulfilled, onRejected){        // 增加兜底函数         const realOnFulfilled = this.isFunction(onFulfilled) ? onFulfilled : (value) => {            return value;        };        const realOnRejected = this.isFunction(onRejected) ? onRejected : (reason) => {            throw reason;        };        // .then的返回值整体是一个promise        const promise = new MPromise((resolve, reject) => {            switch(this.status){                case FULFILLED: {                    realOnFulfilled();                    break;                }                case REJECTED: {                    realOnRejected();                    break;                }            }        })        return promise;    }    // 工具函数 判断是否function    isFunction(value){        return typeof value === 'function'     }

须要思考到promise外部如果是一个异步resolve或者reject办法的状况,此时状态仍是pending.

    // 增加两个数组,存储一部resolve reject办法    FULFILLED_CALLBACK_LIST = [];    REJECTED_CALLBACK_LIST = [];    then(onFulfilled, onRejected){        //...        // .then的返回值整体是一个promise        const promise = new MPromise((resolve, reject) => {            switch(this.status){                // ...                case PENDING: {                    this.FULFILLED_CALLBACK_LIST.push(realOnFulfilled);                    this.REJECTED_CALLBACK_LIST.push(realOnRejected);                    break;                }            }        })        return promise;    }

那么如何去保护FULFILLED_CALLBACK_LIST REJECTED_CALLBACK_LIST这两个数组,到底什么时候去掉用呢?
能够应用es6的get和set去保护

    // 增加一个新的变量来保护状态      _status = PENDING;    get status(){        return this._status;    }    set status(newStatus){        this._status = newStatus;        switch(newStatus){            case FULFILLED: {                this.FULFILLED_CALLBACK_LIST.forEach(callback => {                    callback(this.value);                })                break;            }            case REJECTED: {                this.REJECTED_CALLBACK_LIST.forEach(callback => {                    callback(this.resaon);                })                break;            }        }    }

依据promiseA+标准 onFulfilled 和 onRejected执行的异样,promsie须要被rejected,并且执行后果需调用resolvePromise办法,所以须要对realOnFulfilled 和 realOnRejected函数增加try catch捕捉异样,调用resolvePromise

    then(onFulfilled, onRejected){        // ...        // .then的返回值整体是一个promise        const promise2 = new MPromise((resolve, reject) => {            // onFulfilled 和 onRejected执行的异样,promsie须要被rejected            const fulfilledMircotask = () => {                try{                    const x = realOnFulfilled(this.value);                    this.resolvePromise(promise2, x, resolve, reject);                }catch(e){                    reject(e);                }            }            const rejectedMircotask = () => {                try{                    const x = realOnRejected(this.resaon);                    this.resolvePromise(promise2, x, resolve, reject);                }catch(e){                    reject(e);                }            }            switch(this.status){                case FULFILLED: {                    fulfilledMircotask();                    break;                }                case REJECTED: {                    rejectedMircotask();                    break;                }                case PENDING: {                    this.FULFILLED_CALLBACK_LIST.push(fulfilledMircotask);                    this.REJECTED_CALLBACK_LIST.push(fulfilledMircotask);                    break;                }            }        })        return promise2;    }    resolvePromise(promise2, x, resolve, reject){            }

promise中onFulfilled, onRejected为微工作,应用queueMicroTask进行包裹

        const promise2 = new MPromise((resolve, reject) => {            const fulfilledMircotask = () => {                queueMicrotask(() => {                    try{                        const x = realOnFulfilled(this.value);                        this.resolvePromise(promise2, x, resolve, reject);                    }catch(e){                        reject(e);                    }                })            }            const rejectedMircotask = () => {                queueMicrotask(() => {                    try{                        const x = realOnRejected(this.resaon);                        this.resolvePromise(promise2, x, resolve, reject);                    }catch(e){                        reject(e);                    }                })            }            // ...        })    

step 4

实现resolvePromise办法

    resolvePromise(promise2, x, resolve, reject){        // 如果x promise相等        if(promise2 === x){            return reject(new TypeError('the promise and the return value are the same'))        }        // 如果x是一个promsie 那么让新的promise接口x的状态        // 那继续执行x,如果执行的时候又返回了一个y,那么持续解析y        if(x instanceof MPromise){            // 这里也是执行了promise 须要queueMicrotask包裹下            queueMicrotask(() => {                x.then(y => {                    this.resolvePromise(promise2, y, resolve, reject);                }, reject);            })        }else if(typeof x === 'object' && this.isFunction(x)){            if(x === null){                return reject(x);            }            let then = null;            try{                // 去x.then的值赋值给then                then = x.then;            }catch(e){                return reject(e);            }            // 如果获取的then是一个函数            if(this.isFunction(then)){                // flag 确保只被执行一次                let called = false;                try{                    then.call(                        x,                        (y) => {                            if(called){                                return;                            }                            called = true;                            this.resolvePromise(promise2, y, resolve, reject);                        },                        (r) => {                            if(called){                                return;                            }                            called = true;                            reject(r);                        }                    )                }catch(err){                    if(called){                        return;                    }                    reject(err);                }            }else{                resolve(x);            }        }else{            resolve(x)        }    }

step 5

catch办法实现就很简略了

    catch(onRejected){        this.then(null, onRejected);    }

step 6

除了这些 promsie还有一些静态方法,eg resolve reject。 什么是静态方法?

    static resolve(value){        if(value instanceof MPromise){            return value;        }        return new Promise((resolve, reject) => {            resolve(value);        })    }    static reject(reason){        return new Promise((resolve, reject) => {            reject(reason);        })    }    // race状态是依靠外部执行最快的那个状态    static race(promiseList){        if(!Array.isArray(promiseList)){            return        }        return new Promise((resolve, reject) => {            if(promiseList.length === 0){                resolve();            }else{                promiseList.forEach(promise => {                    MPromise.resolve(promise).then(                        val => resolve(val),                        reason => reject(reason)                    )                })            }        })    }    static all(promiseList){        if(!Array.isArray(promiseList)){            return        }        return new Promise((resolve, reject) => {            if(promiseList.length === 0){                resolve([]);            }else{                let count = [];                let res = [];                promiseList.forEach((promise, index) => {                    MPromise.resolve(promise).then(                        val => {                            res[index] = val;                            count++;                            if(count === promiseList.length){    // 可否用 index === promiseList.length 来做判断  为什么?                                resolve(res)                            }                        },                        reason => reject(reason)                    )                })            }        })    }    //  ...

残缺代码

const PENDING = 'pending';const FULFILLED = 'fulfilled';const REJECTED = 'rejected';class MPromise {    // 增加两个数组,存储一部resolve reject办法    FULFILLED_CALLBACK_LIST = [];    REJECTED_CALLBACK_LIST = [];    _status = PENDING;    /**     * @param {Function} fn (resolve, reject)    */    constructor(fn){        // 初始状态为pending        this.status = PENDING;        this.value = null;        this.reason = null;        try{            fn(this.resolve.bind(this), this.reject.bind(this));    // 为什么须要 bind(this) ?             // 传入的fn可能是一个一般的函数,并不是箭头函数,有他本人的执行环境        }catch(e){            this.reject(e);        }    }        resolve(value){        // 判断状态  只有PENDING才能够批改状态        if(this.status === PENDING){            this.value = value;            this.status = FULFILLED;        }    }    reject(resaon){        // 判断状态  只有PENDING才能够批改状态        if(this.status === PENDING){            this.resaon = resaon;            this.status = REJECTED;        }    }    get status(){        return this._status;    }    set status(newStatus){        this._status = newStatus;        switch(newStatus){            case FULFILLED: {                this.FULFILLED_CALLBACK_LIST.forEach(callback => {                    callback(this.value);                })                break;            }            case REJECTED: {                this.REJECTED_CALLBACK_LIST.forEach(callback => {                    callback(this.resaon);                })                break;            }        }    }    then(onFulfilled, onRejected){        // 增加兜底函数         const realOnFulfilled = this.isFunction(onFulfilled) ? onFulfilled : (value) => {            return value;        };        const realOnRejected = this.isFunction(onRejected) ? onRejected : (reason) => {            throw reason;        };        // .then的返回值整体是一个promise        const promise2 = new MPromise((resolve, reject) => {            // onFulfilled 和 onRejected执行的异样,promsie须要被rejected            const fulfilledMircotask = () => {                queueMicrotask(() => {                    try{                        const x = realOnFulfilled(this.value);                        this.resolvePromise(promise2, x, resolve, reject);                    }catch(e){                        reject(e);                    }                })            }            const rejectedMircotask = () => {                queueMicrotask(() => {                    try{                        const x = realOnRejected(this.resaon);                        this.resolvePromise(promise2, x, resolve, reject);                    }catch(e){                        reject(e);                    }                })            }            switch(this.status){                case FULFILLED: {                    fulfilledMircotask();                    break;                }                case REJECTED: {                    rejectedMircotask();                    break;                }                case PENDING: {                    this.FULFILLED_CALLBACK_LIST.push(fulfilledMircotask);                    this.REJECTED_CALLBACK_LIST.push(fulfilledMircotask);                    break;                }            }        })        return promise2;    }    resolvePromise(promise2, x, resolve, reject){        // 如果x promise相等        if(promise2 === x){            return reject(new TypeError('the promise and the return value are the same'))        }        // 如果x是一个promsie 那么让新的promise接口x的状态        // 那继续执行x,如果执行的时候又返回了一个y,那么持续解析y        if(x instanceof MPromise){            // 这里也是执行了promise 须要queueMicrotask包裹下            queueMicrotask(() => {                x.then(y => {                    this.resolvePromise(promise2, y, resolve, reject);                }, reject);            })        }else if(typeof x === 'object' && this.isFunction(x)){            if(x === null){                return reject(x);            }            let then = null;            try{                // 去x.then的值赋值给then                then = x.then;            }catch(e){                return reject(e);            }            // 如果获取的then是一个函数            if(this.isFunction(then)){                // flag 确保只被执行一次                let called = false;                try{                    then.call(                        x,                        (y) => {                            if(called){                                return;                            }                            called = true;                            this.resolvePromise(promise2, y, resolve, reject);                        },                        (r) => {                            if(called){                                return;                            }                            called = true;                            reject(r);                        }                    )                }catch(err){                    if(called){                        return;                    }                    reject(err);                }            }else{                resolve(x);            }        }else{            resolve(x)        }    }    catch(onRejected){        this.then(null, onRejected);    }    static resolve(value){        if(value instanceof MPromise){            return value;        }        return new Promise((resolve, reject) => {            resolve(value);        })    }    static reject(reason){        return new Promise((resolve, reject) => {            reject(reason);        })    }    // race状态是依靠外部执行最快的那个状态    static race(promiseList){        if(!Array.isArray(promiseList)){            return        }        return new Promise((resolve, reject) => {            if(promiseList.length === 0){                resolve();            }else{                promiseList.forEach(promise => {                    MPromise.resolve(promise).then(                        val => resolve(val),                        reason => reject(reason)                    )                })            }        })    }    static all(promiseList){        if(!Array.isArray(promiseList)){            return        }        return new Promise((resolve, reject) => {            if(promiseList.length === 0){                resolve([]);            }else{                let count = [];                let res = [];                promiseList.forEach((promise, index) => {                    MPromise.resolve(promise).then(                        val => {                            res[index] = val;                            count++;                            if(count === promiseList.length){    // 可否用 index === promiseList.length 来做判断  为什么?                                resolve(res)                            }                        },                        reason => reject(reason)                    )                })            }        })    }    // 工具函数 判断是否function    isFunction(value){        return typeof value === 'function'     }}