手写Promise——Day1

一、resolve与reject代码实现

建议:在看懂后自己多敲两遍,并配合一定例子来进行测试(此笔记的用例均没给出结果,可以和原生Promise的结果进行比对)

代码:

function Promise(executor) { //executor:执行器函数,即同步执行函数
    //给Promise构造函数身上添加两个固定的属性
    this.PromiseState = 'pending';
    this.PromiseResult = null;
    
​
    const self = this; //将self指向Promise
    function resolve(data) {
        //console.log(this),函数内的this指向的是window
        self.PromiseState = 'fulfilled';
        self.PromiseResult = data;
    }
    /*
    也可以使用箭头函数,是this指向Promise
        const resolve = data => {
            this.PromiseState = 'fulfilled';
            this.PromiseResult = data;
        }
    */
    function reject(data) {
        self.PromiseState = 'rejected';
        self.PromiseResult = data;
    }
    
    executor(resolve, reject);
    
}

测试:

<script>
    let p = new Promise((resolve, reject) => {
        resolve('ok');
        // reject('err');
    })
    p.then(value => {
        console.log(value);
    }, reason => {
        console.warn(reason);
    })
        
    console.log(p);
</script>

二、接收throw抛出异常

一般throw抛出异常时,都用 try...catch...语句接收

代码:

function Promise(executor) { 
    this.PromiseState = 'pending';
    this.PromiseResult = null;
​
    const self = this ;
    function resolve(data) {
        self.PromiseState = 'fulfilled';
        self.PromiseResult = data;
    }
    
    function reject(data) {
        self.PromiseState = 'rejected';
        self.PromiseResult = data;
    }
    //是将函数执行的地方包含起来,而不是将所有代码都包含其中
    try {
        executor(resolve, reject);
    } catch (e) {
        reject(e);
    }
    
}

测试:

<script>
    let p = new Promise((resolve, reject) => {
        // resolve('ok');
        // reject('err');
        throw 'error';
    })
    p.then(value => {
        console.log(value);
    }, reason => {
        console.warn(reason);
    })
        
    console.log(p);
</script>

三、Promise对象只允许修改一遍

实现此功能,只需加个对Promise对象状态的判断即可

代码:

function Promise(executor) { 
    this.PromiseState = 'pending';
    this.PromiseResult = null;
​
    const self = this ;
    function resolve(data) {
        if (self.PromiseState !== 'pending') return; //此if语句使PromiseState只能修改一次
        self.PromiseState = 'fulfilled';
        self.PromiseResult = data;
    }
    
    function reject(data) {
        if (self.PromiseState !== 'pending') return //此if语句使PromiseState只能修改一次
        self.PromiseState = 'rejected';
        self.PromiseResult = data;
    }
    try {
        executor(resolve, reject);
    } catch (e) {
        reject(e);
    }
    
}

测试:

<script>
    let p = new Promise((resolve, reject) => {
        resolve('ok');
        reject('err');
    })
    p.then(value => {
        console.log(value);
    }, reason => {
        console.warn(reason);
    })
        
    console.log(p);
</script>

四、then方法回调的同步执行

代码:

Promise.prototype.then = function(onResolved, onRejected) {
    if (this.PromiseState === 'fulfilled') onResolved(this.PromiseResult) //状态为成功时,所执行的回调  
    if (this.PromiseState === 'rejected') onRejected(this.PromiseResult) //状态为失败时,所执行的回调
}

测试:

<script>
    let p = new Promise((resolve, reject) => {
        resolve('ok');
        // reject('err');
    })
    p.then(value => {
        console.log(value);
    }, reason => {
        console.warn(reason);
    })
        
    console.log(p);
</script>

五、then方法回调的异步执行

此处使用定时器来实现异步

代码:

function Promise(executor) { //只写新增加的代码,前面的就不重复写了
    // 添加一个对象属性,用来存储then方法中的两个回调函数
    this.callback = {};
    const self = this;
    function resolve(data) {
        if (self.callback.onResolved) 
            self.callback.onResolved(data);
    }
    function reject(data) {
        if (self.callback.onRejected) 
            self.callback.onRejected(data);
    }
}
​
Promise.prototype.then = function(onResolved, onRejected) {
    if (this.PromiseState === 'fulfilled') onResolved(this.PromiseResult);  
    if (this.PromiseState === 'rejected') onRejected(this.PromiseResult);
    // 当Promise中是异步执行是,会先往下执行then方法,此时状态为'pending'
    if (this.PromiseState === 'pending') {
            this.callback = {
                onResolved,
                onRejected
            }
        /*
        对象的简写形式,相当于:              {onResolved:onResolved,onRejected,onRejected}
        */
}

测试:

<script>
    let p = new Promise((resolve, reject) => {
        setTimeout(()=>{
            resolve('ok');
            // reject('err');
        },1000)
    })
    p.then(value => {
        console.log(value);
    }, reason => {
        console.warn(reason);
    })
        
    console.log(p);
</script>

六、指定多个回调执行的实现

多个回调的执行,只需将存储的方式由对象==>数组即可

代码:

function Promise(executor) { 
    this.callback = [];
    const self = this;
    function resolve(data) {
        // 当执行多个回调时使用数组形式来遍历调用
        self.callback.forEach(item => {
            item.onResolved(data);
        })
    function reject(data) {
        // 当执行多个回调时使用数组形式来遍历调用
        self.callback.forEach(item => {
            item.onRejected(data);
        })
}
        
Promise.prototype.then = function(onResolved, onRejected) {
    if (this.PromiseState === 'pending') {
             //往数组中添加只需使用push()方法即可
             this.callback.push({
                onResolved,
                onRejected
             })
}

测试:

<script>
    let p = new Promise((resolve, reject) => {
            resolve('ok');
            // reject('err');
    })
    p.then(value => {
        console.log(value);
    }, reason => {
        console.warn(reason);
    })
    
     p.then(value => {
        alter(value);
    }, reason => {
        console.warn(reason);
    })
        
    console.log(p);
</script>

七、同步修改then方法返回结果的状态

then方法返回:

1.如果回调函数结果是一个非Promise对象,则返回结果是一个成功的Promise

2.如果回调函数结果是一个Promise对象,则返回结果由该Promise对象决定

代码:

Promise.prototype.then = function(onResolved, onRejected) {
    const self = this //注意:函数内的this指向Window!!!
    return new Promise((resolve, reject) => {
        if (this.PromiseState === 'fulfilled') {
            try { // 来对应回调函数通过throw抛出异常
                // console.log(this)
                //获取回调函数执行的结果
                let result = onResolved(self.PromiseResult);
                //如果回调函数执行结果是Promise对象
                if (result instanceof Promise) {
                    result.then(val => {
                        resolve(val); //是val 不是result
                    }, rea => {
                        reject(rea); //是rea 不是result
                    })
                } else {
                    resolve(result); //此处应该返回是回调函数执行结果,而不是resolve函数执行结果
                    // result(this.PromiseResult) 不对
                }
            } catch (e) {
                reject(e);
            }
        } 
        if (this.PromiseState === 'rejected') {
            try { 
                let result = onRejected(self.PromiseResult); 
                if (result instanceof Promise) {
                    result.then(val => {
                        resolve(val);
                    }, rea => {
                        reject(rea);
                    })
                } else {
                    resolve(result);
                }
            } catch (e) {
                reject(e);
            }
        } 
​
        if (this.PromiseState === 'pending') {
            this.callback.push({
                onResolved,
                onRejected
            });
        }
    });
}

测试:

<script>
    let p = new Promise((resolve, reject) => {
            resolve('ok');
            // reject('err');
            // throw 'fail';
    })
    let res = p.then(value => {
        console.log(value);
        // return 123
        /* return new Promise((resolve,reject) =>{
                resolve('okk');
        })
        */
    }, reason => {
        console.warn(reason);
    })
    
    console.log(res);
</script>

八、异步修改then方法返回结果的状态

代码:

Promise.prototype.then = function(onResolved, onRejected) {
    const self = this //注意:函数内的this指向Window!!!
        if (this.PromiseState === 'pending') {
            this.callback.push({
                onResolved: function(){
                    try {
                        let result = onResolved(self.PromiseResult);
                        if (result instanceof Promise) {
                            result.then(val => {
                                resolve(val); 
                            }, rea => {
                                reject(rea);
                            })
                        } else {
                            resolve(result); 
                        }
                    } catch (e) {
                        reject(e);
                    }
                },
                onRejected: function(){
                    try { 
                        let result = onRejected(self.PromiseResult); 
                        if (result instanceof Promise) {
                            result.then(val => {
                                resolve(val);
                            }, rea => {
                                reject(rea);
                            })
                        } else {
                            resolve(result);
                        }
                    } catch (e) {
                        reject(e);
                    }
            });
        }
    });
}

测试:

<script>
    let p = new Promise((resolve, reject) => {
            setTimeout(()=>{
                resolve('ok');
                // reject('err');
                // throw 'fail';
            },1000)
    })
    let res = p.then(value => {
        console.log(value);
        // return 123
        /* return new Promise((resolve,reject) =>{
                resolve('okk');
        })
        */
    }, reason => {
        console.warn(reason);
    })
    
    console.log(res);
</script>

九、部分代码的优化

因为 then 方法返回结果处有大量重复代码,所有封装函数,优化代码

Promise.prototype.then = function(onResolved, onRejected) {
    const self = this;
    return new Promise((resolve, reject) => {
        function callback(type) {
            try {
                let result = type(self.PromiseResult);
                if (result instanceof Promise) {
                    result.then(val => {
                        resolve(val);
                    }, rea => {
                        reject(rea);
                    })
                } else {
                    resolve(result);
                }
            } catch (e) {
                reject(e);
            }
}

以上代码+注释整合:

function Promise(executor) { //executor:执行器函数,即同步执行函数
    //一旦出现thorw语句,则使用 try...catch...来捕获
    //给Promise构造函数身上添加两个固定的属性
    this.PromiseState = 'pending';
    this.PromiseResult = null;
        // this.callback = {} //用来保存当Promise里面执行的是异步函数时的then方法中的两个回调
    this.callback = [] //当形式为数组是,则用来绑定多个回调
​
    const self = this; //将self指向Promise
    function resolve(data) {
        // console.log(this) 函数体内的this指向window
        if (self.PromiseState !== 'pending') return; //此if语句使PromiseState只能修改一次
        self.PromiseState = 'fulfilled';
        self.PromiseResult = data;
            // if (self.callback.onResolved) self.callback.onResolved(data) //如果是异步执行,则callback中则会含有onResolved / onRejected
            // 当执行多个回调时使用数组形式来遍历调用
        self.callback.forEach(item => {
            item.onResolved(data);
        })
    }
​
    function reject(data) {
        if (self.PromiseState !== 'pending') return; //此if语句使PromiseState只能修改一次
        self.PromiseState = 'rejected';
        self.PromiseResult = data;
            // if (self.callback.onRejected) self.callback.onRejected(data) //如果是异步执行,则callback中则会含有onResolved / onRejected
            // 当执行多个回调时使用数组形式来遍历调用
        self.callback.forEach(item => {
            item.onRejected(data);
        })
    }
    try {
        executor(resolve, reject);
    } catch (e) {
        reject(e);
    }
}
​
Promise.prototype.then = function(onResolved, onRejected) {
​
    /*
        .then方法返回:
            1.如果回调函数结果是一个非Promise对象,则返回一个成功的Promise
            2.如果回调函数结果是一个Promise对象,则返回结果由该Promise对象决定
    */
    const self = this
    return new Promise((resolve, reject) => {
        function callback(type) {
            try {
                //获取回调函数执行的结果
                // console.log(this),注意:函数内的this指向Window!!!
                let result = type(self.PromiseResult);
                    //如果回调函数执行结果是Promise对象
                if (result instanceof Promise) {
                    result.then(val => {
                        resolve(val); //是val 不是result
                    }, rea => {
                        reject(rea); //是rea 不是result
                    })
                } else {
                    resolve(result); //此处应该返回是回调函数执行结果,而不是resolve函数执行结果
                        // result(this.PromiseResult) 不对
                }
            } catch (e) {
                reject(e);
            }
        }
        if (this.PromiseState === 'fulfilled') callback(onResolved); //Promise成功时所执行的回调
        if (this.PromiseState === 'rejected') callback(onRejected); //Promise失败时所执行的回调
​
        //下面为当Promise里面是异步函数时所对应情况
        if (this.PromiseState === 'pending') {
            // this.callback = {
            //     onResolved,
            //     onRejected
            //     //对象的简写形式,相当于{onResolved:onResolved,onRejected,onRejected}
            // }
​
            // this.callback.push({
            //     onResolved,
            //     onRejected
            // })
​
            //异步修改then的返回结果
            this.callback.push({
                onResolved: function() {
                    callback(onResolved);
                },
                onRejected: function() {
                    callback(onRejected);
                }
            })
        }
    })
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三年ing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值