使用js创建异步循环

时间:2019-05-21 23:32:12

标签: javascript node.js loops asynchronous puppeteer

我正在尝试在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 个答案:

答案 0 :(得分:1)

我已经编辑了您的代码,以显示应该如何使用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)
  }
  
})()

答案 1 :(得分:0)

您无法等待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
}