ES6——Promise源码(原生javascript全部实现)

ES6——Promise源码(原生javascript全部实现):

 
 function MyPromise (func) {
            var self = this;
            self.status = 'pending';    //进来时就先定义一个'pending'状态;等待调用时改变状态;
            self.resolveValue = null;   //MyPromise增加两个变量,方便之后储存参数;
            self.rejectReason = null;
        //完成异步操作:
            self.ResolveCallBackList = [];  //存储注册时成功的函数;
            self.RejectCallBackList = [];   //存储失败时成功的函数;
        //完成MyPromise的两个方法:
            function resolve (value) {      //成功的方法;
                if (self.status === 'pending') {
                    self.status = 'Fulfilled';      //成功回调触发'Fulfilled'状态;
                    self.resolveValue = value;      //把传入的'value'形参存到MyPromise中;方便调用.then()时有该参数;
                    self.ResolveCallBackList.forEach(function (ele) { //调用时可执行异步操作;;
                        ele();
                    });
                }
            };
            function reject (reason) {      //失败的方法;
                if (self.status === 'pending') {
                    self.status = 'Rejected';       //失败回调触发'Rejected'状态;
                    self.rejectReason = reason;
                    self.RejectCallBackList.forEach(function (ele) { //调用时可执行异步操作;
                        ele();
                    });
                }
            }
        //同步执行时抛出错误后的兼容:
            try {                           //当抛出错误后直接执行失败的回调函数;
                func(resolve, reject);      //创建MyPromise时就同步执行;
            }catch(e){
                reject(e)
            }
        };
        
        //解决ruturn值的方法:
        function ResolutionReturnPronise (nextPromise, returnValue, res, rej) {
            //可以利用,之后的.then()注册的回调函数,都是注册在nextPromise身上的这一特点巧妙处理;
            if (returnValue instanceof MyPromise) {  //返回值为Promise时:
                returnValue.then(function (val) {    //直接让返回值链式调用.then()方法
                    res(val);                        //方法中成功方法直接执行成功回调;
                }, function (reason) {
                    rej(reason);                     //失败方法直接执行失败回调;
                })

            }else{                                   //返回值为普通值时
                res(returnValue);                    //会执行成功的回调:
            }

        }
        
        //完善.then()方法:
        MyPromise.prototype.then = function (func1, func2) {  //原方法可插入成功和失败两个方法;
        //处理空then():
            if (!func1) {    //如果为空将参数原封不用返回;
                func1 = function (val) {
                    return val;
                }
            }
            if (!func2) {    //如果为空将错误原封不动返回;
                func2 = function (reason) {
                    throw new Error(reason);
                }
            }
            var self = this;
        //实现原方法调用.then()方法是返回的是一个属性Promise对象;
            var nextPromise = new MyPromise(function (res, rej) {
        //完成同步操作:
                if (self.status === 'Fulfilled') {
        //.then()本身是异步操作:由于没有微任务权限,这里用setTimeout()使每一步为异步操作:
                    setTimeout(function () {
        //完善数据捕获功能;(无论错误出现在成功还是失败中都会在失败的回调中找出)
                        try{
        //                     var nextResolveValue = func1(self.resolveValue);
        // //原方法返回一个普通值时会执行成功的回调:
        //                     res(nextResolveValue);
                            var nextResolveValue = func1(self.resolveValue);
                            ResolutionReturnPronise(nextPromise, nextResolveValue, res, rej);//由于异步执行,此处nextPromise可以直接传进去;
                        }catch(e){
                            rej(e);
                        }
                    }, 0);

                }
                if (self.status === 'Rejected') {
                    setTimeout(function () {
                         try{                   //完善数据捕获功能;
                                var nextRejectValue = func2(self.rejectReason);
                                // res(nextRejectValue); //原方法返回一个普通值时会执行成功的回调;
                                ResolutionReturnPronise(nextPromise, nextRejectValue, res, rej);
                            }catch(e){
                                rej(e);
                            }
                    }, 0);
                }
        //完成异步操作:
                if (self.status === 'pending') {                //如果状态为'pending'
                    self.ResolveCallBackList.push(function () { //注册成功函数时放到成功回调数组中;
                        setTimeout(function () {
                            try{                   //完善数据捕获功能;
                                var nextResolveValue = func1(self.resolveValue);
                                // res(nextResolveValue); //原方法返回一个普通值时会执行成功的回调;
                                ResolutionReturnPronise(nextPromise, nextResolveValue, res, rej);
                            }catch(e){
                                rej(e);
                            }
                        }, 0);

                    });
                    self.RejectCallBackList.push(function () {  //注册失败函数时放到成功回调数组中;
                        setTimeout(function () {
                            try{                   //完善数据捕获功能;
                                var nextRejectValue = func2(self.rejectReason);
                                // res(nextRejectValue); //原方法返回一个普通值时会执行成功的回调;
                                ResolutionReturnPronise(nextPromise, nextRejectValue, res, rej);
                            }catch(e){
                                rej(e);
                            }
                        }, 0);
                    });
                }
            });
        //完成链式调用:
            return nextPromise;  //要知道:之后的.then()注册的回调函数,都是注册在nextPromise身上的;
        };
        
        //完善.race()方法:
        MyPromise.race = function (promiseArr) {
            return new MyPromise(function (resolve, reject){
                promiseArr.forEach(function (promise, index){
                    promise(resolve, reject);     //哪个状态最先改变一定会先触发;
                });
            });
        };
        
        //完善.all()方法:
        MyPromise.all = function (promiseArr) {
            return new MyPromise(function (resolve, reject){
                if(!Array.isArray(promiseArr)){
                    return reject(new TypeError("argument must be anarray"));
                }
                var countNum = 0;
                var promiseNum = promiseArr.length;
                var resolvedvalue = new Array(promiseNum);
                for(var i = 0; i < promiseNum; i++){
                    (function (i) {
                        promiseArr[i].then(function (value) {  //对每一个数组中的Promise对象进行单独.then();
                            countNum++;
                            resolvedvalue[i] = value;
                            if(countNum === promiseNum){
                                return resolve(resolvedvalue)  //全部成功时,输出所有的已存到数组中的结果;
                            }
                        },function (reason) {
                            return reject(reason);             //否则输出该最先被reject(reason) 的状态值;
                        });
                    })(i);
                }
            });
        };


        //测试MyPromise:
        const oMP = new MyPromise( (res, rej) => {
            // res('同步操作');
            setTimeout(function () {
                res('异步操作');
                // rej('异步操作');

            }, 500)
        })
        oMP.then( (val) => {
            console.log(val + '-成功回调');
            // return '成功';
            // throw new Error('抛出错误');
            return new MyPromise((res, rej) => {
                res('return Promise')
            });
        }, (reason) => {
            console.log(reason + '-失败回调');
            // return '失败';
            throw new Error('抛出错误');
        }).then( (val) => {
            console.log(val + '-成功回调1');
        }, (reason) => {
            console.log(reason + '-失败回调2');
        });

        function text (num) {
           return new MyPromise( (resolve, reject) => {    //return new Promise();
               setTimeout( () => {    //进行一个异步操作;
            // resolve(num);  //假设全部成功:执行结果为:[ 'a', 'b', 'c' ]
                Math.random() *100 > 50 ? resolve(num) : reject(num); //随机数大于50执行成功,否则执行失败;
                }, 100)
            });
        }
        const oMP1= MyPromise.all([text('a'), text('b'), text('c')])
        .then( val => {
            console.log('成功:' + val);         //全成功时才会触发成功回调;结果为:[ 'a', 'b', 'c' ]
        },(reason) => {
            console.log('失败:' + reason);      //有一个失败就返回最先被reject(num)的状态值;结果可能为 a || b || c;
        });
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值