【问题标题】:How do I execute an Array<Function> in parallel [closed]如何并行执行 Array<Function> [关闭]
【发布时间】:2020-04-03 23:49:20
【问题描述】:

我有一个带有回调函数的数组,所以是Array&lt;Function&gt; | Array&lt;AsyncFunction&gt;。我正在尝试找到一种方法并行调用这些回调

如果我有一份承诺清单,我知道Promise.all 会这样做。但是我的投入并没有成功地完成这项工作

所以要添加更多细节:

假设我有一个这样的匿名函数数组

let callbacks = [
    () => {console.log('callback')},
    () => {console.log('another callback');
    () => {console.log('final callback');
];

并行执行这些回调的最佳方式是什么?

【问题讨论】:

  • 是的,很难知道你在做什么,因为你的问题太模糊了
  • @JaromandaX 我尝试添加更多关于我正在尝试做的事情的细节

标签: javascript typescript promise parallel-processing


【解决方案1】:

Javascript 在设计上是单线程语言。所以引擎只能同时解析一个函数。
这些函数被堆叠到调用堆栈中并由事件循环处理。这意味着,即使有了 Promise,引擎也一次只处理一个函数。
使用Promise.all([...]),您可以委派处理这些调用的责任,以便在解决所有承诺后继续运行您的代码(在then 方法内或等待中)。
这并不意味着所有的 Promise 都是并行执行的。


通过使用称为 Web Workershttps://www.sitepoint.com/javascript-web-workers/

的多引擎系统来解决此问题

【讨论】:

    【解决方案2】:

    如果您计划在每个回调中执行的工作是异步的,那么 .forEach() 应该适合您。

    .forEach() 调用将立即运行,启动所有异步调用,并且不会等到前一个异步调用解决后再开始下一个异步调用。由于它们都是异步的,因此它们只会在 .forEach() 循环中开始。

    let callbacks = [
        async () => {console.log('callback')},
        async () => {console.log('another callback')},
        async () => {console.log('final callback')},
    ];
    
    callbacks.forEach(c => c());
    

    【讨论】:

      【解决方案3】:

      要从函数创建 Promise,只需使用 new Promise(executor) constructor

      您可以在阵列上使用map“批量”执行此操作。

      然后你可以在你的阵列上使用Promise.all()

      let callbacks = [
          () => {console.log('callback')},
          () => {console.log('another callback')},
          () => {console.log('final callback')},
      ];
      Promise.all(callbacks.map(f => new Promise((resolve) => { 
          f(); 
          resolve();
      }))).then(() => 
      {
          console.log("All resolved.");
      })

      我鼓励你查看 MDN 上关于 Promises 的文章。

      请注意,在上面的 sn-p 中,一旦在 callbacks.map 中创建了 Promise,回调就会开始执行。 如果由于某种原因您需要分两步完成此操作,并且您想首先创建“冷”承诺,此问答提供了一些线索和解决方案:Creating a (ES6) promise without starting to resolve it

      另外,正如VRoxa mentionned,这不是“并行”计算(多线程),而是“异步”计算。我假设您正在考虑后者,因为您提到了Promise.all。这个问答可以澄清条款:How to articulate the difference between asynchronous and parallel programming?

      【讨论】:

      • 这行得通。但问题是我们从来没有解决任何这些承诺。所以这基本上会导致后续语句永远不会被执行。如果我等待Promise.all(callbacks.map(f =&gt; new Promise(f))),我们将永远无法通过该声明,因为承诺将始终处于未决状态
      • @Meru-kun 确实,我写的原始答案没有用。我编辑了我的代码以提供一个更明智的示例,解决了您提到的问题。
      猜你喜欢
      • 2012-12-06
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 2012-08-07
      • 1970-01-01
      • 2015-08-15
      • 2015-12-27
      相关资源
      最近更新 更多