手写Promise——Day2

一、catch方法的实现

catch方法是用来捕获一个失败的Promise对象,然后在返回一个失败的Promise对象

代码:

//直接调用then方法来返回一个失败结果
Promise.prototype.catch = function(onRejected) {
    return this.then(undefined, onRejected);
}

测试:

<script>
    let p = new Promise((resolve, reject) => {
        reject('err');
        // resolve('ok');
    })
​
    p.catch((reason) => {
            console.warn(reason)
    })
​
    console.log(p)
    //当返回一个失败Promise时,如果不被catch,则会报错
</script>

二、异常穿透与值传递

代码:

Promise.prototype.then = function(onResolved, onRejected) {
    //只写了新需求的代码,之前重复的就没写了
    return new Promise((resolve, reject) => {
        //实现异常穿透时,通常会省略onRejected回调函数,所以我们需要在底层实现该逻辑
        if (typeof onRejected !== 'function') {
            onRejected = rea => {
                throw rea // throw会返回一个失败的Promise
                /*
                    如果返回的一个成功的Promise或者非Promise类型,则不会被cathch捕获到
                    如:return rea
                        console.log(rea)
                */
            }
        }
        //实现值传递时,可能会省略onResolved回调函数,所以我们需要在底层实现该逻辑
        if (typeof onResolved !== 'function') {
            onResolved = val => {
                return val;
            }
        }
    }
}

测试:

<script>
    let p = new Promise((resolve, reject) => {
        reject('err');
        // resolve('ok');
    })
​
    //异常穿透,只要有一个出错,就被捕获到catch中去
    p.then(value => {
        console.log(111);
    }).then(value => {
        console.log(222);
    }).then(value => {
        console.log(333);
    }).catch(reason => {
        console.warn(reason)
    })
    
    //值传递,对应需要成功回调
    p.then()
    .then(value => {
        console.log(222);
    }).then(value => {
        console.log(333);
    })
    
    console.log(p)
</script>

三、resolve方法的实现

该方法是Promise构造函数身上的一个方法,且返回对象和then方法是一样的

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

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

代码:

//所以该代码实现逻辑和then方法中类似
Promise.resolve = function(value) {
    return new Promise((resolve, reject) => {
        if (value instanceof Promise) {
            value.then(val => {
                resolve(val);
            }, rea => {
                reject(rea);
            })
        } else {
            resolve(value);
        }
    });
}

测试:

<script>
    let p1 = Promise.resolve('ok');
    let p2 = Promise.resolve(new Promise((resolve, reject) => {
        resolve('okkk');
    }));
    let p3 = Promise.resolve(new Promise((resolve, reject) => {
        reject('err');
    }));
    console.log(p1,p2,p3);
</script>

四、reject方法的实现

该方法总是返回一个失败的Promise

代码:

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

测试:

<script>
    let p1 = Promise.reject('err');
    let p2 = Promise.reject(new Promise(resolve,reject) => {
        resolve('ok');
    })
    console.log(p1,p2);
</script>

五、all方法的实现

该方法接收一个promise数组,只有当这个数组中的所有promise成功时,才返回成功的Promise对象,但如果有一个失败,则返回其失败的Promis

代码:

Promise.all = function(promises) {
    let count = 0; //来计算数组中成功promise的数量
    let arr = [];
    return new Promise((resolve, reject) => {
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(val => {
                count++;
                arr[i] = val; //此处不能使用数组的push()方法,因为当Promise中有异步执行时,会打乱顺序(如下测试中的p2,如果使用的是push方法,则会先将p3的结果存入数组,后将p2的结果存入)
                if (count === promises.length)
                    resolve(arr);
            	}, rea => {
                	reject(rea);
            });
        }
    });
}

测试:

<script>
    let p1 = Promise.resolve('ok');
    let p2 = Promise.resolve(new Promise((resolve, reject) => {
        // resolve('okkk');
        setTimeout(() => {
            resolve('okkk');
        }, 1000)
    }));
    let p3 = Promise.resolve(new Promise((resolve, reject) => {
        reject('err');
        // resolve('lkd');
    }));
    const promises = [p1, p2, p3];
    let ps = Promise.all(promises)
    console.log(ps)
</script>

六、race方法的实现

该方法也需要传入一个promise数组,但它只要有一个先成功或者先失败,就返回其Promise结果

代码:

Promise.race = function(promises) {
    return new Promise((resolve, reject) => {
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(val => {
                resolve(val);
            }, rea => {
                reject(rea);
            });
        }
    });
}

测试:

<script>
    // let p1 = Promise.resolve('ok');
    let p2 = Promise.resolve(new Promise((resolve, reject) => {
        // reject('err');
        setTimeout(()=>{
            resolve('lkd');
        },1000)
    }));
    let p3 = Promise.reject('error');
    // const promises = [p1, p2, p3];
    const promises = [p2,p3]
    let pn = Promise.race(promises)
    console.log(pn)
</script>

七、实现then回调的异步执行

代码:

function Promise(executor) { 
    function resolve(data) {
        setTimeout(() => {
            self.callback.forEach(item => {
                item.onResolved(data)
            })
        })
    }

    function reject(data) {
        setTimeout(() => {
            self.callback.forEach(item => {
                item.onRejected(data)
            })
        })
}

Promise.prototype.then = function(onResolved, onRejected) {
    return new Promise((resolve, reject) => {
        if (this.PromiseState === 'fulfilled') {
            setTimeout(() => {
                callback(onResolved) 
            })
        }
        if (this.PromiseState === 'rejected') {
            setTimeout(() => {
                callback(onRejected) 
            })
        }
    })
}

测试:

<script>
    let p = new Promise((resolve, reject) => {
        resolve('ok');
        console.log('111');
    })

    p.then(val=>{
        console.log('222');
    })

    console.log('333');
    /*
    	此测试如果没有实现then回调的异步执行,则会输出:
    		111
    		222
    		333
    */
</script>
  • 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、付费专栏及课程。

余额充值