ждет, когда веб-работник сделает http-вызов - PullRequest
0 голосов
/ 28 февраля 2020

Я создаю несколько веб-работников, делающих http-звонки. Я должен ограничить количество веб-работников, и поэтому я пытаюсь дождаться, пока некоторые из работников закончат работу sh.

. Вот пример того, что, по моему мнению, может работать с использованием Promises:

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

Я думал, что это подождет, пока каждое обещание будет решено, прежде чем перейти к следующему пункту ... но это не так.

Что я мог бы сделать, чтобы это сработало? или ... я также думал о создании массива рабочих и запуске рекурсивного l oop, который проверяет / ждет, пока один из них станет доступным ... Я открыт для общих предложений по решению этой проблемы.

1 Ответ

1 голос
/ 28 февраля 2020

.map() не обещает знать. Он не смотрит на возвращаемое значение из каждой итерации, чтобы увидеть, является ли это обещанием, а затем приостанавливает l oop. Вместо этого он просто вслепую выполняет все итерации одну за другой. Когда вы возвращаете обещания от .map(), которые вы используете с обратным вызовом async, это просто означает, что ваши .map() будут выдавать массив обещаний, и все ваши итерации l oop будут "в полете" одновременно время, не упорядоченное.

Если вы хотите выполнить итерацию al oop и приостановить l oop в каждой итерации до разрешения обещания, тогда используйте обычное for l oop:

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);
        });
    }
}

К вашему сведению, вызовы http в Javascript неблокируемые и асинхронные, поэтому не совсем понятно, почему вы делаете их в WebWorkers. Если вы не интенсивно используете процессор для обработки результата, вы можете выполнять запросы http в основном потоке без каких-либо блокировок.


Также к вашему сведению, для ряда различных вариантов обработки массива, только с N запросами в полете одновременно (где вы решаете, какое значение N), смотрите эти различные ответы:

runN(fn, limit, cnt, options): L oop через API на несколько запросов

pMap(array, fn, limit): Сделайте несколько запросов к API, который может обрабатывать только 20 одновременно

rateLimitMap(array, requestsPerSec, maxInFlight, fn): Правильный асинхронный c метод для максимальных запросов в секунду

mapConcurrent(array, maxConcurrent, fn): Promise.all () потребляет весь мой оперативный памяти

Существуют также функции для этого встроенные в Библиотека обещаний Bluebird и Asyn c -обещающая библиотека .

...