自定义封装实现Promise

自定义封装实现Promise

//原promise对比
// let p = new Promise((resolve, reject) => {
        //     var ids = setTimeout(()=>{
        //         resolve("success");
        // reject("false");
        // },1000)
        // clearTimeout(ids);
        // reject("false");
        // throw("ERROR")
        // })
        // console.log(p);
        // let x = new Promise(() => {});
        // console.log(x);

        // let result = p.then(value => {
        //     console.log(value);
        // throw("ERROR2")
        // }, reason => {
        // console.log(reason);
        // return new Promise((resolve, reject) => {
        //     throw("ERROR2")
        // })
        // }).then(value => {
        //     console.log(value,"xxx");
        // }, reason => {
        //     console.log(reason,"yyy");
        // return new Promise((resolve, reject) => {
        //     throw("ERROR1")
        // })
        // })

        // p.then(value => {
        //     alert(value)
        // }, reason => {
        //     console.log(reason);
        // })
        // console.log(result,"sasas");
        // console.log(p);

        let p = new Promise((resolve, reject) => {
            var ids = setTimeout(() => {
                // resolve("success");
                // throw "false"
                reject("false")
            }, 1000)
        })
        p.then(() => {
            console.log(111);
        }).then(() => {
            console.log(222);
        }).then(() => {
            console.log(333);
        }).catch((error) => {
            console.log(error);
        })

let x = Promise.resolve("aaa")
        console.log(x);
let y = Promise.resolve(new Promise((resolve, reject) => {reject("false")}))
        console.log(y);
//Promise.js

function Promise(executer){
    this["[[PromiseState]]"] = "pending";
    this.callback = {};
    let self = this;
    function resolve(data){
        if(self["[[PromiseState]]"] !== "pending") return;
        self["[[PromiseState]]"] = "resolved";
        self["[[PromiseResult]]"] = data;
        //if(self.callback.onResolved) self.callback.onResolved(data);
        //self.callbacks.forEach(item => item.onResolved(data));
        setTimeout(()=>{
            self.callbacks.forEach(item => item.onResolved(data));
        })
    }

    function reject(data){
        if(self["[[PromiseState]]"] !== "pending") return;
        self["[[PromiseState]]"] = "rejected";
        self["[[PromiseResult]]"] = data;
        //if(self.callback.onResolved) self.callback.onRejected(data);
       //self.callbacks.forEach(item => item.onRejected(data));
        setTimeout(()=>{
            self.callbacks.forEach(item => item.onRejected(data));
        })
    }

    try {
        executer(resolve,reject);
    } catch (error) {
        reject(error);
    }
}

Promise.prototype.then = function(onResolved,onRejected){
    /*
    this["[[PromiseState]]"] === "resolved" ? onResolved(this["[[PromiseResult]]"]) : this["[[PromiseState]]"] === "rejected" ? onRejected(this["[[PromiseResult]]"]) : this.callback = {onResolved,onRejected};
    */
    /*
    this["[[PromiseState]]"] === "resolved" ? onResolved(this["[[PromiseResult]]"]) : this["[[PromiseState]]"] === "rejected" ? onRejected(this["[[PromiseResult]]"]) : this.callbacks.push({onResolved,onRejected});
    */
    /*
    return new Promise((resolve,reject) => {
        let result = this["[[PromiseState]]"] === "resolved" ? onResolved(this["[[PromiseResult]]"]) : this["[[PromiseState]]"] === "rejected" ? onRejected(this["[[PromiseResult]]"]) : this.callbacks.push({onResolved,onRejected});
        result instanceof Promise ? result.then(v => resolve(v),r => reject(r)) : resolve(result);
    })
    */
    /*
    return new Promise((resolve,reject) => {
       try {
            let result = this["[[PromiseState]]"] === "resolved" ? onResolved(this["[[PromiseResult]]"]) : this["[[PromiseState]]"] === "rejected" ? onRejected(this["[[PromiseResult]]"]) : this.callbacks.push({onResolved,onRejected});
            result instanceof Promise ? result.then(v => resolve(v),r => reject(r)) : resolve(result);
       } catch (error) {
           reject(error);
       }
    })
    */
    /*
     return new Promise((resolve,reject) => {
       if(this["[[PromiseState]]"] === "resolved"){
            try {
                let result = onResolved(this["[[PromiseResult]]"]);
                if(result instanceof Promise){
                    result.then(v => resolve(v),r => reject(r))
                }else{
                    resolve(result)
                }
            } catch (error) {
                reject(error); 
            }
       }
       if(this["[[PromiseState]]"] === "rejected"){
        onRejected(this["[[PromiseResult]]"])
       }
       if(this["[[PromiseState]]"] === "pending"){
        this.callbacks.push({onResolved,onRejected})
       } 
    })
    */
    /*
    return new Promise((resolve,reject) => {
    	let self = this;
       	if(self["[[PromiseState]]"] === "resolved"){
            try {
                let result = onResolved(self["[[PromiseResult]]"]);
                if(result instanceof Promise){
                    result.then(v => resolve(v),r => reject(r))
                }else{
                    resolve(result)
                }
            } catch (error) {
                reject(error); 
            }
       }
       if(self["[[PromiseState]]"] === "rejected"){
         try {
                let result = onRejected(self["[[PromiseResult]]"]);
                if(result instanceof Promise){
                    result.then(v => resolve(v),r => reject(r))
                }else{
                    resolve(result)
                }
            } catch (error) {
                reject(error); 
            }
       }
       if(self["[[PromiseState]]"] === "pending"){
        self.callbacks.push({onResolved:function(){
            try {
                let result = onResolved(self["[[PromiseResult]]"]);
                if(result instanceof Promise){
                    result.then(v => resolve(v),r => reject(r))
                }else{
                    resolve(result)
                }
            } catch (error) {
                reject(error); 
            }
        },onRejected:function(){
            try {
                let result = onRejected(self["[[PromiseResult]]"]);
                if(result instanceof Promise){
                    result.then(v => resolve(v),r => reject(r))
                }else{
                    resolve(result)
                }
            } catch (error) {
                reject(error); 
            }
        }})
       } 
    })
    */
    return new Promise((resolve,reject) => {
       let self = this;
        if(typeof onResolved !== "function"){
            onResolved = value => value;
        }
    	if(typeof onRejected !== "function"){
            onRejected = reason => {
                throw reason;
            }
        }
       function callback(excute){
        try {
            let result = excute(self["[[PromiseResult]]"]);
            if(result instanceof Promise){
                result.then(v => resolve(v),r => reject(r))
            }else{
                resolve(result)
            }
        } catch (error) {
            reject(error); 
        }
       }
       if(this["[[PromiseState]]"] === "resolved"){
            //callback(onResolved)
           setTimeout(()=>{
               callback(onResolved)
            })
       }
       if(this["[[PromiseState]]"] === "rejected"){
            //callback(onRejected)
           setTimeout(()=>{
                callback(onRejected)
            })
       }
       if(this["[[PromiseState]]"] === "pending"){
        this.callbacks.push({onResolved:function(){
            callback(onResolved)
        },onRejected:function(){
            callback(onRejected)
        }})
       } 
    })
}

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

Promise.resolve = function(value){
    return new Promise((resolve,reject) => {
        value instanceof Promise ? value.then(v => resolve(v),r => reject(r)) : resolve(value);
    })
}

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

Promise.all = function(promises){
    return new Promise((resolve,reject) => {
        let resarr = [];
        let count = 0;
        promises.forEach((item,index) => {
            item.then(v => {
                count++;
                resarr[index] = v;
                if(count === promises.length) resolve(resarr);
            },r => {
                reject(r);
            })
        })
    })
}

Promise.race = function(promises){
    return new Promise((resolve,reject) => {
        promises.forEach(item => {
            item.then(v => {
               resolve(v);
            },r => {
                reject(r);
            })
        })
    })
}

拆分解析

//executer	执行函数参数,传入Promise对象的是一个回调函数
//resolve和reject	executer()函数的参数是两个函数参数

//Promise.prototype.then	实例化Promise对象后仍旧可以调用then属性指向函数代表then属性是原型链上原型对象属性

//self = this	储存this指向,防止丢失
//self.PromiseState	Promise对象的状态改变
//self["[[PromiseResult]]"] = data	返回结果为传入参数

//if(self["[[PromiseState]]"] !== "pending") return		Promise对象状态只能改变一次

//try catch		Promise状态改变的三种方式:resolve、reject、throw,后两者返回状态皆为rejected

//三目运算符调用:三种状态的处理
//this.callback = {onResolved,onRejected}	处理异步,存在异步时,将then的参数储存在对象上,在状态改变时进行调用
//his.callback => his.callbacks	//考虑到多次调用Promise.then也可执行,若callback为对象,则多次调用会产生覆盖而只执行最后一个then

//return new Promise()	Promise对象then方法执行后返回一个Promise对象
//声明result变量	then方法返回的值若不是Promise对象,则作为值传入resolve执行,是Promise对象则执行then方法且状态与上一个返回的Promise对象状态相同

//放弃三目运算符的原因:存在bug,异步执行Promise对象状态为挂起时,变量result接收undefined,继续向后执行,与预期效果相悖,先换回if else,后期优化再做考虑

//4个try cache	暂未考虑代码冗余问题,此处处理Promise对象异步执行结束后状态未按照原Promise改变仍旧为pending的问题

//function callback	函数封装解决代码冗余

//typeof...		Promise.then可以值传递

//Promise.prototype.catch	捕获异常且可以异常穿透

//Promise.resolve	实例化对象不具有的resolve属性,快速创建Promise对象

//Promise.reject	实例化对象不具有的reject属性,快速创建Promise对象

//Promise.all	数组中元素状态全为resolve时,状态为resolved,返回结果为数组元素返回结果组成的数组,否则状态为rejected。返回结果为第一个状态改变为rejected的数组元素

//Promise.race	数组中第一个元素的状态和返回结果决定了该方法的状态与返回结果

//setTimeout(()=>{})	then方法为异步调用

封装为类

class Promise{
    constructor(executer){
        this["[[PromiseState]]"] = "pending";
        this.callbacks = [];
        let self = this;
        function resolve(data){
            if(self["[[PromiseState]]"] !== "pending") return;
            self["[[PromiseState]]"] = "resolved";
            self["[[PromiseResult]]"] = data;
            setTimeout(()=>{
                self.callbacks.forEach(item => item.onResolved(data));
            })
        }
    
        function reject(data){
            if(self["[[PromiseState]]"] !== "pending") return;
            self["[[PromiseState]]"] = "rejected";
            self["[[PromiseResult]]"] = data;
            setTimeout(()=>{
                self.callbacks.forEach(item => item.onRejected(data));
            })
        }
    
        try {
            executer(resolve,reject);
        } catch (error) {
            reject(error);
        }
    }

    then(onResolved,onRejected){
        let self = this;
        if(typeof onResolved !== "function"){
            onResolved = value => value;
        }
        if(typeof onRejected !== "function"){
            onRejected = reason => {
                throw reason;
            }
        }
        return new Promise((resolve,reject) => {
           function callback(excute){
            try {
                let result = excute(self["[[PromiseResult]]"]);
                if(result instanceof Promise){
                    result.then(v => resolve(v),r => reject(r))
                }else{
                    resolve(result)
                }
            } catch (error) {
                reject(error); 
            }
           }
           if(this["[[PromiseState]]"] === "resolved"){
               setTimeout(()=>{
                   callback(onResolved)
                })
           }
           if(this["[[PromiseState]]"] === "rejected"){
                setTimeout(()=>{
                    callback(onRejected)
                })
           }
           if(this["[[PromiseState]]"] === "pending"){
            this.callbacks.push({onResolved:function(){
                callback(onResolved)
            },onRejected:function(){
                callback(onRejected)
            }})
           } 
        })
    }
    
    catch(onRejected){
        return this.then(undefined,onRejected);
    }
    
    static resolve(value){
        return new Promise((resolve,reject) => {
            value instanceof Promise ? value.then(v => resolve(v),r => reject(r)) : resolve(value);
        })
    }
    
    static reject(reason){
        return new Promise((resolve,reject) => {
            reject(reason);
        })
    }
    
    static all(promises){
        return new Promise((resolve,reject) => {
            let resarr = [];
            let count = 0;
            promises.forEach((item,index) => {
                item.then(v => {
                    count++;
                    resarr[index] = v;
                    if(count === promises.length) resolve(resarr);
                },r => {
                    reject(r);
                })
            })
        })
    }
    
    static race(promises){
        return new Promise((resolve,reject) => {
            promises.forEach(item => {
                item.then(v => {
                   resolve(v);
                },r => {
                    reject(r);
                })
            })
        })
    }
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值