【Promise高级用法】实现并行和串行API

Promise高级用法


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


串行API

提示:这里可以添加本文要记录的大概内容:
1、案例:实现一个promise队列----传入一个promise数组,一次串行执行并输出他们的成功或者失败结果


提示:以下是本篇文章正文内容,下面案例可供参考

一、思路总结

promise串行的实现基本思路是:

1、第一种是在前一个promise处于解决状态后执行下一个promise(也就是then方法中)
2、第二种则是通过递归调用的思路来依次执行promise

二、实现

1.代码实现

代码如下(示例):基于递归思想实现

function queuePromise(promiseArr) {
    return new Promise((resolve, reject) => {
        let arrLen = promiseArr.length;
        let resArr = [];
        if (!Array.isArray(promiseArr) || arrLen === 0) return console.error('必须传入非空数组!', Array.isArray(promiseArr) , arrLen);
        let ArrStatus = promiseArr.every(item => {
            return item instanceof Promise;
        });
        if (!ArrStatus) return console.error('数组第每一项必须是promise');
        try {
            let num = 0;
            function run(num) {
                if (num >= arrLen) {
                    resolve(resArr);
                    return;
                };
                console.log('开始执行:'+num);
                promiseArr[num].then((res) => {
                        resArr.push({
                            status: 1,
                            res,
                        });
                        console.log(res + '=>');
                        run(++num);
                    }, err => {
                        console.log(err + '-->');
                        resArr.push({
                            status: 0,
                            err,
                        });
                        run(++num);
                    });
            };
            run(num);
        } catch (error) {
            reject(error);
        }
    })
};
let arr = [new Promise(resolve => {
    setTimeout(_ => {
        resolve('3s');
    }, 3000);
}), new Promise(resolve => {
    setTimeout(_ => {
        resolve('8s');
    }, 3000);
}), new Promise((resolve, reject) => {
    setTimeout(_ => {
        resolve('18s');
        // reject('18s');
    }, 3000);
})];
// queuePromise(arr).then(res => {
//     console.log('queuePromise=>', res);
// }).catch(err => {
//     console.log('queuePromise-err=>', err);
// });

并行API

提示:这里可以添加本文要记录的大概内容:
1、案例:实现一个promise.All这样的并行API


提示:以下是本篇文章正文内容,下面案例可供参考

一、思路总结

promise并行的实现基本思路是:

1、第一种是for循环的实现方式,但是值得注意的是:

  • 如果是异步写法for()、for of 和arr.forEach()实现是一致的都是互不干扰的并行模式
  • 如果是async await的同步写法for()、for of实现将会是阻塞的串行方式,但是arr.forEach实现仍然是并行效果,因为forEach方法运行时候会独立开启自调用函数作用域
  • 但是这两种实现并行都是没有固定开始执行顺序的

2、第二种通过arr.reduce取迭代执行,这只实现并行效果因为胃任务队列的原因会有先后执行的顺序

二、实现

1.代码实现

代码如下(示例):基于reduce思想实现

// 并行 但是由于微任务机制它们执行纯在先后顺序
let allPromise =  (promiseArr) => {
    let arrLen = promiseArr.length;
    let resArr = [];
    if (!Array.isArray(promiseArr) || arrLen === 0) return console.error('必须传入非空数组!', Array.isArray(promiseArr) , arrLen);
    let ArrStatus = promiseArr.every(item => {
        return item instanceof Promise;
    });
    if (!ArrStatus) return console.error('数组第每一项必须是promise');
    return new Promise((resolve, reject) => {
        // console.log('quePromise+>', Array(...Array(arrLen).keys()));
        Array(...Array(arrLen).keys()).reduce((promise, index) => {
            console.log('------>', index, promise);
            return promiseArr[index].then(res=> {
                resArr.push({
                    status: 1,
                    res,
                });
                console.log(res + '=>');
                (index == arrLen - 1) && resolve(resArr);
            }, err => {
                resArr.push({
                    status: 0,
                    err,
                });
                console.log(err + '-->');
                (index == arrLen - 1) && resolve(resArr);
            });
        }, Promise.resolve('1'));
    });
}

quePromise(arr).then(res => {
    console.log('quePromise:', res);
})

代码如下(示例):基于forEach思想实现

// 实现promise.all----并行
let promiseAll = function(promiseArr) {
    let arrLen = promiseArr.length;
    let resoveCount = 0;
    let resArr = new Array(arrLen);
    if (!Array.isArray(promiseArr) || arrLen === 0) return console.error('必须传入非空数组!', Array.isArray(promiseArr) , arrLen);
    let ArrStatus = promiseArr.every(item => {
        return item instanceof Promise;
    });
    if (!ArrStatus) return console.error('数组第每一项必须是promise');
    return new Promise((resolve, reject) => {
        promiseArr.forEach((promise, index) => {
            promise.then(res => {
                resArr[index] = res;
                resoveCount ++;
                if (resoveCount === arrLen) resolve(resArr);
            }, err => {
                reject(err);
            });
        });
    }

代码如下(示例):基于forEach思想实现

// promise.race ---并行

function promiseRace(promiseArr) {
    let arrLen = promiseArr.length;
    let status = false;
    if (!Array.isArray(promiseArr) || arrLen === 0) return console.error('必须传入非空数组!', Array.isArray(promiseArr) , arrLen);
    let ArrStatus = promiseArr.every(item => {
        return item instanceof Promise;
    });
    if (!ArrStatus) return console.error('数组第每一项必须是promise');
    return new Promise((resolve, reject) => {
        try {
            promiseArr.forEach((item, index) => {
                if (!status) {
                    item.then(res => {
                        resolve(res);
                        status = true;
                    }, error => {
                        reject(error);
                    })
                };
            });
        } catch (error) {
            reject(error);
        }
    })
};


let raceArr = [
    new Promise((resolve, reject) => {
        setTimeout(_ => {
            resolve('race-----3s');
        }, 3000);
    }),
    new Promise((resolve, reject) => {
        setTimeout(_ => {
            resolve('race-----2s');
        }, 2000);
    }),
    new Promise((resolve, reject) => {
        setTimeout(_ => {
            resolve('race-----5s');
        }, 5000);
    }),
];

总结

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

LuckyCola2023

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

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

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

打赏作者

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

抵扣说明:

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

余额充值