promise 实现(es6 完整源码)

发布时间:2019-08-09 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了promise 实现(es6 完整源码)脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

概览

const PENDING = Symbol('PENDING');
const FULFILLED = Symbol('FULFILLED');
const REJECTED = Symbol('REJECTED');

class MyPromise {
    constructor(fn) {}
    then(successFn, failFn) {}
    catch(failFn) {}
    finally(finalFn){}
    static resolve(val) {}
    static reject(val) {}
    static all(PRomiseArr) {}
    static race(promiseArr) {}
}

Promise 内部维护着三种状态 pendingfulfilledrejected,状态只能从 pending 转变到 fulfilled,或从 pending 转变到 rejected 且该转变不可逆。

Promise 主要提供了三个实例方法 then,catchfinally,和4个静态方法 resolve,reject,all,race。所有方法都都返回一个Promise对象。

构造函数

    constructor(fn) {
        this.fulfilledQueue = [];
        this.rejectedQueue = [];
        this._status = PENDING;
        this._value  = null;

        // 执行成功队列中的回调函数
        const handleFulfilledQueue = () => {
            while(this.fulfilledQueue.length) {
                let fulfiledFn = this.fulfilledQueue.shift();
                fulfiledFn(this._value);
            };
        };
        
        // 执行失败队列中的回调函数
        const handleRejectedQueue = () => {
            while(this.rejectedQueue.length) {
                let rejectedFn = this.rejectedQueue.shift();
                rejectedFn(this._value);
            };
        };

        // 完成状态转变,执行回调队列中的回调函数
        const _resolve = (val) => {
            const fn = () => {
                if(this._status !== PENDING) {
                    return;
                }
                if(val instanceof MyPromise) {
                    val.then((res) => {
                        this._status = FULFILLED;
                        this._value = res;
                        handleFulfilledQueue();
                    }, (err) => {
                        this._status = REJECTED;
                        this._value = err;
                        handleRejectedQueue();
                    });
                } else {
                    this._status = FULFILLED;
                    this._value = val;
                    handleFulfilledQueue();
                }
            }
            // 保证promise 回调函数一定是在同步任务之后执行;
            setTimeout(fn, 0);
        }
        // 完成状态Pending到REJECTED的转变,执行rejected队列中的回调函数
        const _reject = (val) => {
            const fn = () => {
                if(this._status !== PENDING) {
                    return;
                }
                this._status = REJECTED;
                this._value = val;
                handleRejectedQueue();
            }
            setTimeout(fn, 0);
        }
        
        try {  // 处理外部传入函数执行异常
            fn(_resolve, _reject);            
        } catch(e) {
            return _reject(e);
        }
    }

Promise 构造函数接收一个函数执行器作为参数,该执行器的两个参数 _resolve、_reject均为函数类型,由 Promise 内部实现。执行器在 Promise 构造函数中被立即执行。

注意: MyPromise 使用 Timeout 实现异步,使得 MyPromise 只能添加 macrotask,实际上原生的Promise 是 microtask

then 方法

    then(successFn, failFn) {
        return new MyPromise((resolve, reject) => {
            // 执行成功时的回调函数
            const handleSucess = (fn) => {
                try {
                    if(typeof fn === 'function') {
                        const res = fn(this._value);
                        if(res instanceof MyPromise) {
                            res.then(resolve, reject);
                        } else {
                            resolve(res);
                        }
                    } else {
                        resolve(this._value)
                    }
                } catch(e){
                    reject(e);
                }
            }
            // 执行失败时的回调函数
            const handleFail = (fn) => {
                try {
                    if(typeof fn === 'function') {
                        const res = fn(this._value);
                        if(res instanceof MyPromise) {
                            res.then(resolve, reject);
                        } else {
                            resolve(res);
                        }
                    } else {
                        reject(this._value);
                    }
                } catch(e) {
                    reject(e);
                }
            }
            switch(this._status){
                case PENDING:       // 异步任务尚未完成,将回调函数推入相应队列
                    this.fulfilledQueue.push(() => {
                        handleSucess(successFn);
                    });
                    this.rejectedQueue.push(() => {
                        handleFail(failFn);
                    });
                    break;
                case FULFILLED:     // 异步任务成功完成,执行成功回调函数
                    handleSucess(successFn);
                    break;
                case REJECTED:      // 异步任务已失败,执行失败回调函数
                    handleFail(failFn);
                    break;
                default:
                    console.log('Promise error status:', this._status);
                    break;
            };
        });
    }

then 方法是 Promise 的一个主要方法,catchfinally 都可以用 then 来实现。当 Promise 的状态已经流转时,回调函数会立即被执行,当 Promise 还处于 Pending 状态时,回调函数被推入相应队列中等待执行。

完整代码

class MyPromise {
    constructor(fn) {
        this.fulfilledQueue = [];
        this.rejectedQueue = [];
        this._status = PENDING;
        this._value  = null;

        const handleFulfilledQueue = () => {
            while(this.fulfilledQueue.length) {
                let fulfiledFn = this.fulfilledQueue.shift();
                fulfiledFn(this._value);
            };
        };
        const handleRejectedQueue = () => {
            console.log(this.rejectedQueue);
            while(this.rejectedQueue.length) {
                let rejectedFn = this.rejectedQueue.shift();
                rejectedFn(this._value);
            };
        };

        // 完成状态转变,执行回调队列中的回调函数
        const _resolve = (val) => {
            const fn = () => {
                if(this._status !== PENDING) {
                    return;
                }
                if(val instanceof MyPromise) {
                    val.then((res) => {
                        this._status = FULFILLED;
                        this._value = res;
                        handleFulfilledQueue();
                    }, (err) => {
                        this._status = REJECTED;
                        this._value = err;
                        handleRejectedQueue();
                    });
                } else {
                    this._status = FULFILLED;
                    this._value = val;
                    handleFulfilledQueue();
                }
            }
            setTimeout(fn, 0);
        }
        // 完成状态Pending到REJECTED的转变,执行rejected队列中的回调函数
        const _reject = (val) => {
            const fn = () => {
                if(this._status !== PENDING) {
                    return;
                }
                this._status = REJECTED;
                this._value = val;
                handleRejectedQueue();
            }
            setTimeout(fn, 0);
        }
        
        try { // 处理外部传入函数执行异常
            fn(_resolve, _reject);            
        } catch(e) {
            
            return _reject(e);
        }
    }

    then(successFn, failFn) {
        return new MyPromise((resolve, reject) => {
            // 执行成功时的回调函数
            const handleSucess = (fn) => {
                try {
                    if(typeof fn === 'function') {
                        const res = fn(this._value);
                        if(res instanceof MyPromise) {
                            res.then(resolve, reject);
                        } else {
                            resolve(res);
                        }
                    } else {
                        resolve(this._value)
                    }
                } catch(e){
                    reject(e);
                }
            }
            // 执行失败时的回调函数
            const handleFail = (fn) => {
                try {
                    if(typeof fn === 'function') {
                        const res = fn(this._value);
                        if(res instanceof MyPromise) {
                            res.then(resolve, reject);
                        } else {
                            resolve(res);
                        }
                    } else {
                        reject(this._value);
                    }
                } catch(e) {
                    reject(e);
                }
            }
            switch(this._status){
                case PENDING:       // 异步任务尚未完成,将回调函数推入相应队列
                    this.fulfilledQueue.push(() => {
                        handleSucess(successFn);
                    });
                    this.rejectedQueue.push(() => {
                        handleFail(failFn);
                    });
                    break;
                case FULFILLED:     // 异步任务成功完成,执行成功回调函数
                    handleSucess(successFn);
                    break;
                case REJECTED:      // 异步任务已失败,执行失败回调函数
                    handleFail(failFn);
                    break;
                default:
                    console.log('Promise error status:', this._status);
                    break;
            };
        });
    }

    catch(failFn) {
        return this.then(null, failFn);
    }

    finally(finalFn){
        return this.then(finalFn, finalFn);
    }

    static resolve(val) {
        if(val instanceof MyPromise) {
            return val;
        } else {
            return new MyPromise((resolve, reject) =>{
                resolve(val);
            });
        }
    }

    static reject(val) {
        return new MyPromise((resolve, reject) => {     
            reject(val);
        });
    }

    static all(promiseArr) {
        return new Promise((resolve, reject) =>{
            const len = promiseArr.length;
            let count = 0;
            let result = [];
            for(let i = 0; i < len; i++) {
                promiseArr[i].then((val) => {
                    count++;
                    result.push[val];
                    if(count === len){
                        resolve(result);
                    }
                }, (err) => {
                    reject(err);
                });
            }
        });
    }

    static race(promiseArr) {
        return new Promise((resolve, reject) =>{
            const len = promiseArr.length;
            for(let i = 0; i < len; i++) {
                promiseArr[i].then((val) => {
                    resolve(val);
                }, (err) => {
                    reject(err);
                });
            }
        });
    }
}

脚本宝典总结

以上是脚本宝典为你收集整理的promise 实现(es6 完整源码)全部内容,希望文章能够帮你解决promise 实现(es6 完整源码)所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。