Promise 静态方法 all、allSettled、race、any 手写

目录

前言

手写代码

all

allSettled

race

any

测试及对比


前言

最近练习了一下 promise 的基本使用,同时也尝试着简单手写一下 promise 的静态方法,这里将它们记录下来,方便日后温习。在下面手写实现的方法中多用到了闭包,如有不了解可以先了解了再来看这篇文章,便于理解。想了解 Promise 相关基础知识请移步 MDN-Promise

手写代码

all

Promise.myAll = function (promises) {
        if(!Array.isArray(promises)) {          //判断一下传入的参数是否为数组
            return Promise.reject(new Error('传入的参数不是数组!'))
        };

        if(!promises.length){
            return Promise.resolve([]);
        }

        let arr = [];
        let num = 0;
        return new Promise((resolve, reject) => {
            promises.forEach((item, index) => {
                Promise.resolve(item).then((value) => { // Promise.resolve(item) 将非 Promise 包装成 Promise
                    num ++;
                    arr[index] = value;
                    if(num === promises.length){
                        resolve(arr);
                    }
                }).catch(reject)  // then 后面第二个参数也可放 reject 或者放 (value) => {reject(value);}
            }
            )
        })
    }

allSettled

Promise.myAllSettled = function(promises){
        if(!Array.isArray(promises)) {          //判断一下传入的参数是否为数组
            return Promise.reject(new Error('传入的参数不是数组!'))
        };

        if(!promises.length){
            return Promise.resolve([]);
        }

        let arr = [];
        let num = 0;
        return new Promise((resolve) => {
            let processing = function(res, index, status, valueOrReason){
                num++;
                let obj = {
                    status:status,
                }
                obj[valueOrReason] = res;
                arr[index] = obj;
                if(num === promises.length){
                    resolve(arr);
                }
            };

            promises.forEach((item, index) => {
                Promise.resolve(item).then((res) => {
                    processing(res, index, 'fulfilled', 'value');
                }, (res) => {
                    processing(res, index, 'rejected', 'reason');
                })
            })
        })
    }

race

Promise.myRace = function(promises){
        if(!Array.isArray(promises)) {          //判断一下传入的参数是否为数组
            return Promise.reject(new Error('传入的参数不是数组!'));
        };
        if(!promises.length){
            return Promise.reject(new Error('All promises were rejected'));
        }

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

any

Promise.myAny = function(promises){
        if(!Array.isArray(promises)) {          //判断一下传入的参数是否为数组
            return Promise.reject(new Error('传入的参数不是数组!'))
        };

        if(!promises.length){
            return Promise.reject(new Error('All promises were rejected'));
        }

        let num = 0;
        return new Promise((resolve, reject) => {
            promises.forEach((item) => {
                Promise.resolve(item).then(resolve, () => {
                    num ++;
                    if(num === promises.length){
                        reject(new Error('没有Promise完成'));
                    }
                })
            })
        })
    }

测试及对比

// Promise 测试数据
    let p1 = function(){
       return  Promise.reject(1);
    }

    let p2 = function(){
        return Promise.reject(2);
    }

    let p3 = function(){
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve(3);
            }, 2001)
        });
    }

    let p4 = function () {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                reject(4);
            }, 2002);
        });
    }

// myAllSettled 测试输出和原方法简单对比,其他几个方法也可进行类似测试
    console.log(Promise.allSettled([p1(), p2(), p3(), p4()]))
    console.log(Promise.myAllSettled([p1(), p2(), p3(), p4()]))
    console.log(Promise.allSettled([]))
    console.log(Promise.myAllSettled([]))

参考资料:https://juejin.cn/post/7069805387490263047#heading-1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值