Создать асинхронный цикл с помощью JS - PullRequest
1 голос
/ 22 мая 2019

Я пытаюсь реализовать асинхронность в каждом цикле на nodejs.

У меня есть переменная html, которая содержит содержимое страницы. Там я хочу перебрать все div, которые имеют определенный класс. Внутри этих div'ов есть несколько ссылок, по которым я хочу перейти и получить от них контент. Таким образом, в основном, так как каждый ожидает синхронную функцию, он не ожидает выполнения другого кода.

Я пытался сделать это так:

const browser = await puppeteer.launch({
    headless: true
});
const page = await browser.newPage();
const page2 = await browser.newPage();
const mainUrl = "http ... ";

const html = await page.goto(mainUrl)
    .then(function() {
        return page.content();
    });

await $('.data-row', html).each(function() => {
    const url = await $(this).find(".link-details a").attr("href");
    page2.goto(url)
        .then(function() {
            const title = await page.evaluate(el => el.innerHTML, await page.$('#title'));
            // do other things 
        });
    // do other things 
    // create a json with data add it to a list  

});

Но заголовок дает неопределенное значение и выполняется после завершения цикла ... Что я могу сделать здесь?

Ответы [ 2 ]

1 голос
/ 22 мая 2019

Я отредактировал ваш код, чтобы показать, как должен использоваться Puppeteer.Ваша главная проблема здесь заключалась в том, чтобы использовать jQuery там, где это было не нужно, и пытаться ожидать вещей, которые не были асинхронными;смешивая в цепочке обещаний.

(async () => {

  const browser = await puppeteer.launch({
      headless: true
  });
  const page = await browser.newPage();
  const page2 = await browser.newPage();
  const mainUrl = "http ... ";

  /*const html = await page.goto(mainUrl)
    .then(function() {
        return page.content();
    });*/
  
  await (page.goto(mainUrl))
  await page.waitForSelector('.data-row');
  const dataRows = await page.evaluate(() =>
    document.querySelectorAll('.data-row');
  )

  /*await $('.data-row', html).each(function() => {
      const url = await $(this).find(".link-details a").attr("href");
      await page2.goto(url)
          .then(function() {
              const title = await page.evaluate(el => el.innerHTML, await page.$('#title'));
              // do other things 
          });
      // do other things 
      // create a json with data add it to a list  

  });*/
  
  for (const row of dataRows) {
    const url = dataRows.querySelector(".link-details a").href;
    await page2.goto(url)
    const title = await page2.evaluate(() => document.title)
    console.log(title)
  }
  
})()
0 голосов
/ 22 мая 2019

Вы не можете ждать jQuery.each, вы можете попробовать сделать следующее.

const rows = await $('.data-row', html).toArray();

for(const row of rows){
    const url = await $(this).find(".link-details a").attr("href");
    page2.goto(url)
        .then(function() {
            const title = await page.evaluate(el => el.innerHTML, await page.$('#title'));
            // do other things 
        });
    // do other things 
    // create a json with data add it to a list
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...