这是我的问题:我有一堆x承诺,我想一次解决5个问题(基本上是Plimit所做的(
这是我为…实现的代码。。。
async queuefy(items, concurrency, callback) {
console.log(items.length);
let queue = [];
let singleQueue = [];
let now = 0;
items.forEach((item, index) => {
now++;
singleQueue.push(item);
if(now === concurrency || index === items.length - 1) {
queue.push(singleQueue);
now = 1;
singleQueue = [];
}
});
let batch = 0;
let ret = [];
for(const que of queue) {
const currentRes = await Promise.all(que.map(async (q) => {
return await callback(q);
}));
console.log("Resolved batch: ", ++batch);
ret.push(...currentRes);
}
ret = ret.filter(ret => ret !== undefined);
return ret;
}
还有更高的逻辑要解决,使用好的ol‘Promise.all的时间会增加;queuefy";。
我的代码有问题吗?或者对于更大的示例,使用Promise.all会降低请求时间吗?
如果在同时请求15个项目和一次最多请求5个请求之间进行选择,则节流/排队实现需要更长的时间,这一点也不奇怪。以前并行进行的工作现在正以半连续的方式进行。据推测,这里使用节流或串行行为并不是为了绝对节省墙上的时钟时间,而是为了均衡服务器负载,或者允许浏览器/网络在其自身的限制范围内优先考虑其他连接。
然而,您可能没有预料到代码的一个方面:您的Promise.all
批5现在需要的时间与下一批开始之前最长的请求一样长。因此,就在新的批处理开始之前,当前打开的请求可能远少于5个。
(A1-------) (B1-----------)(C1--) |
(A2---------) (B2--) (C2-------------------)|
(A3---) (B3-------) (C3------) | done
(A4--------------------)(B4----) (C4----------) |
(A5-----) (B5---------) (C5----) |
TIME->--------------------------------------------------------|
在SO上的PLimit和mine等其他实现中,没有对Promise.all
的中间调用,因此您可以更优化地完成这些调用,同时确保一次不超过5个开放承诺。
( 1-------)( 8-----------)(14--) |
( 2---------)( 9--)(11-------------------) |
( 3---)( 6-------)(10------) | done
( 4--------------------)(13----) |
( 5-----)( 7---------)(12----)(15----------)|
TIME->--------------------------------------|
因此,您可能希望放弃使用Promise.all
,以更好地保持开放通道/线程饱和。