首页 > 解决方案 > 等待进行 http 调用的网络工作者完成

问题描述

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

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

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

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

我能做些什么来完成这项工作?或者......我还考虑过构建一组工作人员并运行一个递归循环来检查/等待一个可用......我愿意接受解决这个问题的一般建议。

标签: promiseasync-awaitweb-worker

解决方案


.map()是不知道的。它不会查看每次迭代的返回值,看看它是否是一个承诺,然后暂停循环。相反,它只是盲目地一个接一个地运行所有迭代。当您返回.map()带有async回调的 Promise 时,这仅意味着您.map()将生成一组 Promise,并且您的所有循环迭代将同时“进行中”,而不是排序。

如果您想迭代一个循环并在每次迭代中暂停循环,直到一个承诺解决,然后使用一个常规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):在多个请求上循环一个 API

pMap(array, fn, limit):向一次只能处理 20 个的 api 发出多个请求

rateLimitMap(array, requestsPerSec, maxInFlight, fn)每秒最大请求的正确异步方法

mapConcurrent(array, maxConcurrent, fn): Promise.all() 消耗了我所有的内存

Bluebird Promise 库Async-promises 库中还内置了一些功能。


推荐阅读