【问题标题】:Is there a limit to how many promises can or should run concurrently?可以或应该同时运行的 Promise 数量是否有限制?
【发布时间】:2019-06-03 06:30:10
【问题描述】:

令人惊讶的是,谷歌在返回这个问题的结果时遇到了麻烦。

我想知道在排队等待下一个完成之前可以或应该并行运行多少个 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
       }

   }
 }

【问题讨论】:

  • depend on the user's internet 并非所有承诺都是基于网络的。它们只是异步的。也许你应该在你的帖子中澄清这一点。
  • 并行还是并发?节点是单线程的。
  • @ayxos 技术上并发。我道歉。据我了解,如果您只是继续发送承诺,它们将同时工作。我想知道是否有办法优化发送多个。感谢您指出了这一点。文字确实有意义。

标签: javascript promise network-programming es6-promise


【解决方案1】:

正如@jfried00 所提到的,运行的承诺数量没有任何限制,因为没有运行Promise 这样的事情。一旦你运行async function 或运行new Promise(res =&gt; 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 上的更多文字。如果您想自己动手,也可以查看源代码...

【讨论】:

    【解决方案2】:

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

    现在,如果一个 Promise 代表一个底层异步操作(它们通常会这样做),那么该特定类型的异步操作可以同时运行的数量很可能存在一些限制。例如,在某些时候,您可能会遇到单个主机可以同时接受多少请求的限制。或者,您可能会在某处遇到与数以万计的连接有关的本地资源问题。

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

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

    如果您知道自己正在处理大量或潜在的大量请求,并且您将为数组中的每个项目发送网络请求,那么通常自己编写一个限制以避免压倒本地资源或目标主机资源。这通常不是通过队列完成的,而是只启动 N 个请求的代码,然后当一个请求完成时,它会启动下一个请求,依此类推。 Bluebird 和 Async 库都有为您管理它的方法。在 Bluebird 中,它是 Promise.map()concurrency 选项。我还亲自编写了多次管理并发连接数的循环,这里是其中一些代码的链接:

    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

    【讨论】:

      猜你喜欢
      • 2018-07-23
      • 2023-03-26
      • 1970-01-01
      • 2015-07-07
      • 1970-01-01
      • 2020-02-18
      • 2012-02-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多