promise简单实现

function isFunction(fn){
    return Object.prototype.toString.call(fn) === '[object Function]';
}

let ST = {
    pending: 0,
    resolved: 1,
    rejected: 2
}

function Promise(fn){
    let self = this;
    self.status = ST.pending;
    self.value = '';
    self.reason = '';
    self.resolveFns = [];
    self.rejectFns = [];

    //setTimeout延迟执行,将reslove执行放在下个循环,保证后续then方法先于它执行,不会出现前面已经resolve了,后面的then还没push进resolveFns数组
    function resolve(val){
        setTimeout(() => {
            if(self.status == ST.pending){
                self.status = ST.resolved;
                self.value = val;
                //用数组保存回调,是为了处理一个promise挂载多个then的情况
                //注意不是链式,这种场景很少出现
                /*
                形如:
                promise.then(resolve1,reject1)
                promise.then(resolve2,reject2)
                promise.then(resolve3,reject3)
                */
                //在链式调用中,该数组通常只会有一个项,就是当前promise的下一个then里面的resolve函数
                //且每次执行,通常都是一个新Promise的resolve数组
                self.resolveFns.forEach(fn => fn());
            }
        })
    }

    function reject(val){
        setTimeout(() => {
            if(self.status == ST.pending){
                self.status = ST.rejected;
                self.reason = val;
                self.rejectFns.forEach(fn => fn());
            }
        })
    }

    //执行出问题,直接reject,Promise的错误默认不会抛出到全局
    try{
        fn(resolve,reject);
    }
    catch(err){
        reject(err);
    }
}

Promise.prototype.then = function(onResolve,onReject){
    let self = this;

    //then每次执行都返回一个新的Promise,then方法要处理前一个promise的三种状态
    return new Promise(function(resolve,reject){
        function handle(value,thenFn){
            let res = isFunction(thenFn) && thenFn(value) || value;
            if(res instanceof Promise){
                res.then(resolve,reject);
            }
            else{
                resolve(res);
            }
        }
    
        //处理三种状态
        //fn函数体里,如果有错误; 会执行try catch里的 reject方法,执行then this.state就是rejected
        //如果没错误且没异步,resolve this.state就是resolved
        //如果没错误且有异步,this.state就是pending
        if(self.status == ST.pending){
            self.resolveFns.push(resloveHandle);
            self.rejectFns.push(rejectHandle);
        }
        else if(self.status == ST.resolved){
            self.handle(self.value,onResolve);
        }
        else if(this.status == ST.rejected){
            self.handle(self.reason,onReject);
        }
    })
}

Promise.prototype.catch = function(onReject){
    return this.then(undefined, onReject);
}

//finally不是promise的末尾,后面还可以有then,所以value和reason必须可以向下传递
Promise.prototype.finally = function(fn){
    let P = this.constructor;
    return this.then(
        value => P.resolve(fn()).then(() => value),
        reason => P.resolve(fn()).then(() => throw reason);
    )
}

//done作为promise的末尾,用于收集所有可能的报错,catch方法捕捉所有错误,并抛出
Promise.prototype.done = function(resolve,reject){
    return this.then(resolve, reject).catch(function(reason){
        setTimeout(function(){
            throw reason;
        });
    })
}

Promise.resolve = function(val){
    return new Promise((resolve) => {
        resolve(val);
    })
}

Promise.reject = function(val){
    return new Promise((resolve,reject) => {
        reject(val);
    })
}

Promise.race = function(promises){
    let len = promises.length;
    
    return new Promise(function(resolve,reject){
        while(len--){
            promises[len].then(resolve,reject);
        }
    })
}

Promise.all = function(promises){
    let len = promises.length,
        results = [];

    return new Promise(function(resolve,reject){
        //用一个数组收集单个promise执行后的结果,收集满数组所有结果,便是所有执行成功
        function reslove(index){
            return function(value){
                results[index] = value;
                if(results.length == len){
                    reslove(results);
                }
            }
        }

        while(len--){
            promises[len].then(resolve(len),reject);
        }
    })
}

原文地址:https://www.cnblogs.com/mengff/p/11740638.html