【问题标题】:Create async loop using js使用js创建异步循环
【发布时间】:2019-10-08 09:26:15
【问题描述】:

我正在尝试在 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  

});

但是标题给出了 undefined 并且它在循环完成执行后执行......我可以在这里做什么?

【问题讨论】:

  • 你在异步闭包中吗?
  • 你混合了等待,然后通过你的所有代码。你不能等待一个 jQuery $().each.

标签: javascript node.js loops asynchronous puppeteer


【解决方案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)
  }
  
})()

【讨论】:

  • for (const row of dataRows) { const url = row.querySelector(".link-details a").href;... 我收到错误 TypeError: dataRows is not iterable
【解决方案2】:

您不能等待 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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-17
    • 2017-12-25
    • 1970-01-01
    • 1970-01-01
    • 2018-10-17
    • 2018-02-01
    • 2018-07-29
    • 1970-01-01
    相关资源
    最近更新 更多