【问题标题】:interject synchronous code into asynchoronous将同步代码插入异步
【发布时间】:2018-07-06 10:25:04
【问题描述】:

我正在针对大约 50 个站点列表运行 lighthouse cli。我只是在.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 实例。如何在一个灯塔完成时暂停执行?

【问题讨论】:

    标签: javascript node.js multithreading asynchronous lighthouse


    【解决方案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() 可以在这些答案中为您做到这一点:

    Make several requests to an API that can only handle 20 request a minute

    Promise.all consumes all my RAM


    Bluebird Promise library 在其Promise.map() function 中也有并发控制。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-24
      • 1970-01-01
      • 2014-02-19
      • 2023-03-12
      • 1970-01-01
      相关资源
      最近更新 更多