Как запустить функцию на основе обещаний поочередно - PullRequest
0 голосов
/ 10 января 2019

Я пытаюсь запустить функцию js Lighthouse узла последовательно (по одному за раз) с массивом URL. Моя проблема в том, что всякий раз, когда я перебираю массив, Lighthouse запускает все URL-адреса одновременно, что, по-моему, проблематично, если у вас очень большой массив URL-адресов.

код:

for(let url of urls) {        
  function launchChromeAndRunLighthouse(url, opts, config = null) {
    return chromeLauncher.launch({chromeFlags: opts.chromeFlags}).then(chrome => {
      opts.port = chrome.port;
      return lighthouse(url, opts, config).then(results => {
        return chrome.kill().then(() => results.lhr)
      });
    });
  }
}

launchChromeAndRunLighthouse('https://example.com', opts).then(results => {
  // Use results!
});

Пожалуйста, помогите! И спасибо за ваше время!

Ответы [ 3 ]

0 голосов
/ 10 января 2019

Мне кажется, я понял это. То, что я сделал, ниже. Пожалуйста, продолжайте отправлять отзывы, если считаете, что это неправильно.

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

async function launchAudit(urls) {
  for (let url of urls) {
     await launchChromeAndRunLighthouse(url, opts).then(results => {
       // Use results!
     });
  };
};

launchAudit(urls);
0 голосов
/ 10 января 2019

Ваш ответ правильный, но его можно улучшить. Поскольку у вас есть доступ к async и await, вы должны полностью использовать его, чтобы сделать свой код чище:

async function launchChromeAndRunLighthouse (url, opts, config = null) {
  const chrome = await chromeLauncher.launch({chromeFlags: opts.chromeFlags});
  opts.port = chrome.port;
  const { lhr } = await lighthouse(url, opts, config);
  await chrome.kill();
  return lhr;
}

async function launchAudit (urls) {
  for (const url of urls) {
     const results = await launchChromeAndRunLighthouse(url, opts);
     // Use results!
  };
}

launchAudit(urls);
0 голосов
/ 10 января 2019

Просто чтобы выполнить ваш код в качестве теста, мы будем использовать async / await и IIFE
Затем создаст функцию, которая поместит весь наш запрос в массив неразрешенных обещаний, чтобы мы могли использовать его с Promise.all()
Вам нужно переписать код примерно так:

(async() => {
  const promisesToExecute = [];

  const launchChromeAndRunLighthouse = async (url, opts, config = null) => {
     const chrome = await return chromeLauncher.launch({chromeFlags: opts.chromeFlags});
     opts.port = chrome.port;

     promisesToExecute.push(lighthouse(url, opts, config));
  }

  const results = await Promise.all(promisesToExecute);

  for(const result of results) {
    const resolvedResult = await result.kill();
    // here you can access your  results.lhr
    console.log(resolvedResult.lhr);
  }
})()

Обратите внимание, , этот код не был проверен, поэтому могут быть проблемы с kill() в результате. Но главная цель - ответить на ваш вопрос и объяснить, как выполнять обещания.
Кроме того, если вы не хотите выполнять все обещания одновременно, вы можете использовать Promise.waterfall с некоторым пакетом npm, например this

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...