【2021-08-18】Promise race、all、allSettled示例和简易并发学习

学习文章:https://www.cnblogs.com/longlongdan/p/13962460.html

const promiseOne = new Promise((resolve, reject) => {
    resolve(111)
})

const promiseTwo = new Promise((resolve, reject) => {
    reject(222)
})

const promiseThree = new Promise((resolve, reject) => {
    resolve(333)
})

// 子任务出错,全部就出错
Promise.all([promiseOne, promiseTwo, promiseThree]).then(res => {
    console.log(Array.prototype.filter.call(res, Boolean)); //[ 111, 333 ]
}).catch(err => { throw Error("all 出错!") })
// 输出:UnhandledPromiseRejectionWarning: Error: all 出错!



Promise.allSettled([promiseOne, promiseTwo, promiseThree]).then(res => {
    console.log(Array.prototype.filter.call(res, Boolean));
    return Array.prototype.filter.call(res, Boolean)
}).catch(err => { throw Error("allSettled 出错!") }).finally(() => {
    console.log('结束...')
});
/*
[
  { status: 'fulfilled', value: 111 },
  { status: 'rejected', reason: 222 },
  { status: 'fulfilled', value: 333 }
]
结束...
*/

简易并发测试代码

// https://www.cnblogs.com/longlongdan/p/13962460.html
function asyncPools(poolLimit, array, fnInter) { // 并发限制实现: 并发为2
    let doing = [];
    let i = 0;
    let ret = [];

    function run() {
        if (i >= array.length) {
            //最后一个resolve状态,会进入外层返回Promise.then
            return Promise.resolve();
        }
        let e = fnInter(array[i++]);
        // e.then(() => doing.splice(doing.indexOf(e), 1))
        e.then(() => {
            doing.splice(doing.indexOf(e), 1);
        }).catch(err => err)
        doing.push(e);
        ret.push(e);
        if (doing.length >= poolLimit) {
            // 监听每完成一个就再放一个
            // race: 哪个 Promise 对象最快得到结果,就返回那个结果,不管结果本身是成功状态还是失败状态。
            return Promise.race(doing).then(run);
        } else {
            // 改写一下保证then链式调用
            return Promise.resolve().then(run);
        }
    }
    // 只有当array结束,最后一个resolve才会进入then
    // 注意:这不管是all还是allSettled,子任务失败时都会返回【主要是race函数的作用】
    return run().then(() => Promise.all(ret));
    // return run().then(() => Promise.allSettled(ret));
}






const moment = require('moment');
// 模拟请求操作
const timeout = i => new Promise((resolve, reject) => {
    setTimeout(() => {
        // 自定义错误提醒
        if (i === 3000) {
            // console.log(param, ' failed')
            return reject({
                status: '请求超时!',
                data: i,
                date: moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
            })
        }
        // console.log(i);
        // 正常通过的数据
        resolve({
            status: 'success',
            data: i,
            date: moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
        });
    }, i)
}).catch(err => err);











asyncPools(2, [1000, 5000, 3000, 2000], timeout)
    .then(res => {
        console.log(res)
    }).catch(err => {
        throw Error(err)
    }).finally(() => {
        console.log('结束...')
    });





asyncPools(2, [2000, 1000, 4000, 2000], timeout)
    .then(res => {
        console.log(res)
    }).catch(err => {
        throw Error(err)
    }).finally(() => {
        console.log('结束...')
    });

输出

[
  { status: 'success', data: 2000, date: '2021-08-18 14:07:33' },
  { status: 'success', data: 1000, date: '2021-08-18 14:07:32' },
  { status: 'success', data: 4000, date: '2021-08-18 14:07:36' },
  { status: 'success', data: 2000, date: '2021-08-18 14:07:35' }
]
结束...
[
  { status: 'success', data: 1000, date: '2021-08-18 14:07:32' },
  { status: 'success', data: 5000, date: '2021-08-18 14:07:36' },
  { status: '请求超时!', data: 3000, date: '2021-08-18 14:07:35' },
  { status: 'success', data: 2000, date: '2021-08-18 14:07:37' }
]
结束...
function asyncPools(factory, maxRun /*并发最大数量*/ , intiArray = [] /*初始化任务列表*/ , startIndex = 0, executing = [] /*运行中*/ ) {
    let results = []; // 结果集
    function promiseMax() {
        // 最后一个resolve状态,会进入外层返回Promise.then
        if (startIndex >= intiArray.length) return Promise.resolve();
        let mi = intiArray[startIndex++]
        let pro = factory(mi); // 当前任务对象
        if (pro instanceof Promise) {
            pro.then(() => {
                executing.splice(executing.indexOf(pro), 1);
            }).catch(err => err)
            executing.push(pro);
            results.push(pro);
        }

        // 监听每完成一个就再放一个
        if (executing.length >= maxRun) {
            // race: 哪个 Promise 对象最快得到结果,就返回那个结果,不管结果本身是成功状态还是失败状态。
            return Promise.race(executing).then(promiseMax);
        } else {
            // 改写一下保证then链式调用
            return Promise.resolve().then(promiseMax);
        }
    }
    // 注意:这不管是all还是allSettled,子任务失败时都会返回【主要是race函数的作用】
    return promiseMax().then(() => Promise.all(results));
}

第一种写法

// 模拟请求操作
const timeout = i => new Promise((resolve, reject) => {
    setTimeout(() => {
        // 自定义错误提醒
        if (i === 3000) {
            // console.log(param, ' failed')
            return reject({
                status: 'error',
                data: i,
                date: moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
            })
        }
        console.log(i);
        // 正常通过的数据
        resolve({
            status: 'success',
            data: 200,
            date: moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
        });
    }, i)
}).catch(err => err); // 这里对应reject的status状态信息啦



// /*模拟函数: 这里模拟延迟操作*/
asyncPools(timeout, 5, [1000, 5000, 3000, 2000, 7000, 1000, 5000, 3000, 2000, 1000]).then(res => {
    console.log(res)
}).catch(err => {
    throw Error(err)
}).finally(() => {
    console.log('结束...')
});

第二种写法


/*模拟函数: 这里模拟延迟操作*/
asyncPools((i) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            // 自定义错误提醒
            if (i === 3000) {
                // console.log(param, ' failed')
                return reject({
                    status: 'error',
                    data: i,
                    date: moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
                })
            }
            console.log(i);
            // 正常通过的数据
            resolve({
                status: 'success',
                data: 200,
                date: moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
            });
        }, i)
    }).catch(err => err); // 这里对应reject的status状态信息啦
}, 5, [1000, 5000, 3000, 2000, 7000, 1000, 5000, 3000, 2000, 1000]).then(res => {
    console.log(res)
}).catch(err => {
    throw Error(err)
}).finally(() => {
    console.log('结束...')
});

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CSDN IT狂飙上传的代码均可运行,功能ok的情况下才上传的,直接替换数据即可使用,小白也能轻松上手 【资源说明】 基于MATLAB实现的有限差分法实验报告用MATLAB中的有限差分法计算槽内电位;对比解析法和数值法的异同点;选取一点,绘制收敛曲线;总的三维电位图+使用说明文档 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2020b;若运行有误,根据提示GPT修改;若不会,私信博主(问题描述要详细); 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可后台私信博主; 4.1 期刊或参考文献复现 4.2 Matlab程序定制 4.3 科研合作 功率谱估计: 故障诊断分析: 雷达通信:雷达LFM、MIMO、成像、定位、干扰、检测、信号分析、脉冲压缩 滤波估计:SOC估计 目标定位:WSN定位、滤波跟踪、目标定位 生物电信号:肌电信号EMG、脑电信号EEG、心电信号ECG 通信系统:DOA估计、编码译码、变分模态分解、管道泄漏、滤波器、数字信号处理+传输+分析+去噪、数字信号调制、误码率、信号估计、DTMF、信号检测识别融合、LEACH协议、信号检测、水声通信 5、欢迎下载,沟通交流,互相学习,共同进步!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值