Вставлять синхронный код в асинхронный

Я работаю на маяке с примерно 50 сайтами. Я просто запускаю его в .forEach Цикл, который, если я понимаю, блокирует, ака, синхронный. Тем не менее, я получаю сразу 50 экземпляров Chrome Canary. В моем ограниченном понимании этих вещей я думаю, что поток запускается синхронно, но потом node может передать поток ядру и с радостью начать следующий. Опять же, это только мое волнообразное понимание того, что происходит.

Я использую эту функцию, которую я извлек откуда-то:

function launchChromeAndLighthouse(url, opts, config = null) {
  return chromeLauncher.launch({chromeFlags: opts.chromeFlags}).then(chrome => {
    opts.port = chrome.port;
    return lighthouse(url, opts, config).then(results =>
      chrome.kill().then(() => results));
  });
}

Я старался nextTick в петле:

asyncFuncs().then( async (sites) => {
  sites.forEach( (site) => {
    process.nextTick(launchChromeAndRunLighthouse(site.url, opts))
  })
})

Но это все еще порождает кучу экземпляров Chrome. Как я могу приостановить выполнение, пока один маяк завершается?

1 ответ

Решение

Поскольку launchChromeAndRunLighthouse() возвращает обещание пометить, когда оно выполнено, если вы хотите запускать их последовательно по одному, вы можете переключиться на for цикл и использование await:

asyncFuncs().then( async (sites) => {
  for (let site of sites) {
    await launchChromeAndRunLighthouse(site.url, opts);
  }
});

Если вы пытаетесь собрать все результаты:

asyncFuncs().then( async (sites) => {
    let results = [];
    for (let site of sites) {
      let r = await launchChromeAndRunLighthouse(site.url, opts);
      results.push(r);
    }
    return results;
}).then(results => {
    // all results here
}).catch(err => {
    // process error here
});

Если вы хотите запускать N экземпляров Chrome за один раз, чтобы он первоначально запускал N экземпляров, а затем каждый раз, когда один из них завершается, вы запускаете следующий ожидающий, более сложный для отслеживания количества запущенных экземпляров. Там есть вызов вспомогательной функции pMap() или же mapConcurrent() который может сделать это для вас в следующих ответах:

Сделайте несколько запросов к API, который может обрабатывать только 20 запросов в минуту

Promise.all потребляет всю мою оперативную память


Библиотека Bluebird Promise также имеет контроль параллелизма в Promise.map() функция

Другие вопросы по тегам