可以或应该同时执行多少个承诺是否有限制?

时间:2019-01-08 14:28:29

标签: javascript promise network-programming es6-promise

令人惊讶的是,谷歌无法返回该问题的结果。

我想知道可以或应该并行执行多少个承诺,然后再排队等待下一个承诺完成。我想这可能取决于用户的互联网,但我认为值得一问。

如果它基于用户的ISP /连接类型,是否有一种方法可以在启动队列之前测试理想的承诺发送量?

此外,我严格来说是在客户端进行交谈。因此,单线程js。

示例代码:

    function uploadToServer(requestData){
    return Promise((...));
   }

 function sendRequests(requestArray){
    var count = 0;
    for(var requestData in requestArray){
        if(count<idealAmount){
            uploadToServer(idealAmount).then(count--);
            count++;
       }else{
           // Logic to wait before attempting to fire event
       }

   }
 }

2 个答案:

答案 0 :(得分:2)

承诺本身没有特定的编码限制。它们只是一个通知系统,您可以有数百万个就可以了(只要您有足够的内存来容纳这些Javascript对象)。

现在,如果promise表示底层的异步操作(通常这样做),那么可以同时运行多少种特定类型的异步操作可能会有一些限制。例如,在某个时候,您可能会遇到一个限制,即单个主机同时要接受您的请求数量。或者,您可能会遇到本地资源问题,某个地方的连接数不胜数。

对于诸如node.js磁盘I / O操作这样的事情,底层的磁盘I / O子系统已经具有一个排队系统,因此实际上只有少量操作一次运行,其余的排队。 >

因此,要回答有关可以进行多少个并发操作的问题,只能在特定类型的异步请求甚至有时甚至特定类型的接收主机的上下文中进行分析和回答。

如果您知道要处理的是大型或潜在大型的请求数组,并且将针对该数组中的每个项目发送网络请求,则通常自己编写一个限制,以避免使本地资源或资源不堪重负目标主机资源。通常,这不是使用队列来完成的,而是仅启动N个请求,然后在一个请求完成时启动下一个请求的代码,依此类推。 Bluebird和Async库都具有为您管理此方法的方法。在Bluebird中,它是concurrency的{​​{1}}选项。我还手动编写了一些循环代码,这些循环自己管理几次并发连接的数量,以下是一些代码的链接:

Promise.all consumes all my RAM

Javascript - how to control how many promises access network in parallel

Make several requests to an API that can only handle 20 request a minute

Loop through an api get request with variable URL

Choose proper async method for batch processing for max requests/sec

Nodejs: Async request with a list of URL

答案 1 :(得分:0)

正如@ jfried00所提到的,对运行的诺言没有任何限制,因为没有运行Promise这样的事情。一旦运行async function或运行类似new Promise(res => something(res))的代码,该方法就会运行。

您可以做的是限制要解决的承诺链的数量:

// ten promises ago:
let oldPromise = doSomethingAsync();

// and now:
oldPromise.then(doSomethingNewAsync());

但是实际上,像我自己的示例所示,自己进行编码会使头发染成灰色相当快-错误处理,找到空插槽并保持流程正确顺序将很困难。

那是有可能的,我将毫不客气地插入此处的我的框架Scramjet完成了您所需要的:

DataStream.from(requestArray)
    .setOptions({maxParallel: 4})
    .unorder(requestData => uploadToServer(requestData))
    .run()

Scramjet将保留4个诺言,但不会尝试保持顺序(还有其他方法),您可以使用任何函数-如果它不返回诺言,则其工作原理与确实一样。这是unordered transforms in scramjet上的更多文本。如果您愿意自己做的话,还可以查看源代码...