等待 web worker 完成 http 调用

waiting for web worker making http call to finish

我正在创建多个进行 http 调用的网络工作者。我必须限制 web worker 的数量,所以我正在等待一些 worker 完成。

这是我认为可以使用 Promises 的示例:

anArray.map(async contact => {
    await new Promise((res, rej) => {
          const worker = new Worker('./http.worker', { type: 'module' });
          worker.onmessage = () => {
            res();
          };
          worker.postMessage(contact);
    });
});

我认为这会等待每个承诺解决后再继续下一个项目...但事实并非如此。

我该怎么做才能完成这项工作?或者...我还考虑过构建一个工人数组和 运行 一个递归循环,checks/waits 一个可用的...我愿意接受解决这个问题的一般建议。

.map() 没有承诺意识。它不会查看每次迭代的 return 值来查看它是否是一个承诺,然后暂停循环。相反,它只是盲目地一次又一次地运行所有迭代。当你 return 从 .map() 承诺你在 async 回调中时,这只意味着你的 .map() 将产生一个承诺数组,你所有的循环迭代将是 "in-flight"同时,未排序。

如果你想迭代一个循环并在每次迭代中暂停循环直到承诺解决,然后使用常规 for 循环:

async function someFunc() {
    for (let contact of anArray) {
        await new Promise((res, rej) => {
              const worker = new Worker('./http.worker', { type: 'module' });
              worker.onmessage = () => {
                res();
              };
              worker.postMessage(contact);
        });
    }
}

仅供参考,Javascript 中的 http 调用是非阻塞和异步的,因此不完全清楚您为什么要在 WebWorkers 中执行它们。除非您对结果进行 CPU 密集处理,否则您可以在主线程中很好地执行 http 请求而不会阻塞它。


另外仅供参考,对于处理数组的许多不同选项,同时只有 N 个请求在运行(您决定 N 的值),请参阅以下各种答案:

runN(fn, limit, cnt, options):

pMap(array, fn, limit):

rateLimitMap(array, requestsPerSec, maxInFlight, fn): Proper async method for max requests per second

mapConcurrent(array, maxConcurrent, fn):

Bluebird promise library and the Async-promises library.

中也内置了执行此操作的功能