几百个数据,Promise.all 没做控制并发?那你心可真大啊!

开发 前端
随后大佬们提出解决方案:控制并发,大佬们是真的强,感觉这种东西已经是大佬们的常规操作了。

需求

我最近在做一个需求:批量去往数据库里存储一些东西,数量可能一次性达到几百个,也就意味着我需要一次性往数据库里存储几百次,我是这么做的:

const save = (data) => {
// 数据库操作(Promise)
return insert(data)
}
const datas = [...几百个数据]
// 进行存储
Promise.all(datas.map(save))

被呵斥

正当我觉得这个需求很轻松的时候。。在 Code Review 上,我被团队的大佬们给呵斥了一顿,理由是:存储的操作发生在服务器,服务器是很脆弱的,你一次性存储几百个,服务器崩了怎么办?

随后大佬们提出解决方案:控制并发,大佬们是真的强,感觉这种东西已经是大佬们的常规操作了。。

控制Promise.all并发

意思就是,比如我有几百个存储操作,我不能一次性去全部执行,而是要控制一次性只能执行10个操作,10个中有一个执行完了,就拿还没执行的操作补上去,就这样一直到这几百个操作全部执行完为止。。

其实很简单,可以直接用库,比如async-pool、es6-promise-pool、p-limit,只要是能用库的,我建议不要自己去写,因为不定因素很多,你自己写的肯定没有库写的好,你说呢~

简单实现

看到一位兄弟实现的挺不错的,链接:https://segmentfault.com/a/1190000016389127

这是async-pool这个库的核心源码:

function asyncPool(poolLimit, array, iteratorFn) {
let i = 0;
const ret = [];
const executing = [];
const enqueue = function () {
// 边界处理,array为空数组
if (i === array.length) {
return Promise.resolve();
}
// 每调一次enqueue,初始化一个promise
const item = array[i++];
const p = Promise.resolve().then(() => iteratorFn(item, array));
// 放入promises数组
ret.push(p);
// promise执行完毕,从executing数组中删除
const e = p.then(() => executing.splice(executing.indexOf(e), 1));
// 插入executing数字,表示正在执行的promise
executing.push(e);
// 使用Promise.rece,每当executing数组中promise数量低于poolLimit,就实例化新的promise并执行
let r = Promise.resolve();
if (executing.length >= poolLimit) {
r = Promise.race(executing);
}
// 递归,直到遍历完array
return r.then(() => enqueue());
};
return enqueue().then(() => Promise.all(ret));
}

大概的逻辑可以总结为:

  • 从array第1个元素开始,初始化promise对象,同时用一个executing数组保存正在执行的promise
  • 不断初始化promise,直到达到poolLimt
  • 使用Promise.race,获得executing中promise的执行情况,当有一个promise执行完毕,继续初始化promise并放入executing中
  • 所有promise都执行完了,调用Promise.all返回

使用方式:

const timeout = i => new Promise(resolve => setTimeout(() => resolve(i), i));
return asyncPool(2, [1000, 5000, 3000, 2000], timeout).then(results => {
...
});
责任编辑:庞桂玉 来源: 前端大全
相关推荐

2021-08-16 10:40:36

数据库耦合

2023-12-14 08:41:29

El-selectNodevue2

2023-10-04 07:25:59

JavaScriptpromises

2020-08-03 10:52:35

Python自动化工具

2019-03-04 08:32:01

DBA数据库JDBC

2021-01-12 13:29:20

数据神经网络

2022-06-02 14:00:41

网络攻击黑客勒索攻击

2013-07-23 16:43:28

Android开源项目

2024-03-29 10:10:16

异常Promise

2015-06-11 16:22:51

数据中心

2012-02-01 10:13:04

2011-05-24 09:47:07

Cisco思科网络管理

2013-04-27 16:44:54

大数据大数据全球技术峰会

2010-03-10 17:15:02

核心交换机

2024-04-09 16:24:18

Promise开发

2010-04-16 16:49:00

WPS Office

2022-12-27 09:57:41

线程数CPU

2022-02-22 10:30:49

Kubernetes集群

2010-02-01 15:24:04

网络核心交换机
点赞
收藏

51CTO技术栈公众号