盒子
盒子

nodejs中如何控制请求的并发数量

面试问题:

现在有10个请求,如何做到同时处理三个请求。

大体思路:

设置当前请求数和最大限制,当请求数小于限制,继续发送请求;当请求数大于限制时,将请求压入请求队列。当一个请求收到响应后,在请求队列头弹出一个请求发送。

代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
concurrent = (limit, array, iteratorFn) => {
let i = 0;
const ret = []
const executing = []
const enqueue = function () {
// 边界处理
if ( i === array.length()){
return Promise.resolve()
}

// 每当一个请求处理完成,就初始化一个promise实例
const item = array[i++]
const p = Promise.resolve().then(() => {iteratorFn(item, array)})
// push到promise数组
ret.push(p)
// 删除执行完的promise
const e = p.then(() => executing.splice(executing.indexOf(e), 1))
executing.push(e)

let r = Promise.resolve()
if (executing.length >= limit) {
// 最先处理完的请求
r = Promise.race(executing)
}
// 递归
return r.then(() => enqueue)
};
// 返回所有的处理结果
return enqueue().then(() => Promise.all(ret))
}

代码流程如下:

1、首先遍历array数组,从第一个元素开始,实例化promise对象。

2、当promise达到上限时,使用Promise.race()获取executing中最先处理完的。

3、删除处理完的请求,实例化新的promise。

4、直到遍历完整个目标请求数组,调用Promise.all()返回。

这里是一个叫async-pool第三方库,可以实现相同功能的还有es6-promise-poolp-limit等库,可以使用npm安装,看源代码深入理解。

同时还有一篇文章:

如何对Promise限流:实现一个Promise.maphttps://juejin.im/post/6844903907651485710

欢迎关注公众号
扫码关注我的微信公众号-大前端合集
  • 微信公众号-大前端合集