首页 > 解决方案 > 嵌套等待无法正常工作 Puppeteer

问题描述

在这段代码中,我试图过滤掉 ElementHandle 数组的一部分。我检查它是否有效的方法是打印最终过滤数组的长度。它应该是 4,而不是 30。

const ar = await page.$$("li[class*=react-job-listing]");
const shortArray = Array.from(ar).filter(async (el)=> {
    console.log((await (await el.getProperty("innerText")).jsonValue()).includes("Easy Apply"));
    return (await (await el.getProperty("innerText")).jsonValue()).includes("Easy Apply");

});
//console.log((await (await ar[0].getProperty("innerText")).jsonValue()).includes("Easy Apply"));
console.log(shortArray.length);
console.log('hello');

不幸的是,这就是结果。

30
hello
false
false
false
false
true
false
false
true
false
false
false
false
false
false
false
false
true
false
false
false
false
false
false
false
false
false
false
false
true
false

长度的控制台日志出现在过滤器执行之前,它应该是最后一件事。

脚本似乎没有等待等待。这一定是由于多个嵌套等待。但我不知道如何解决它。

我知道这真的很丑陋。但是有一些原因我现在不能使用 page.evaluate 和 DOM 函数。请暂时看一下。

标签: javascriptpuppeteer

解决方案


这不是傀儡师的错。异步函数返回 Promise,因此在Array.from(ar).filter()每个 callbak 中返回 thruthy 值并且没有过滤掉任何内容。使用for..of循环进行异步操作更简单、更安全:

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();

const html = `
  <!doctype html>
  <html>
    <head><meta charset='UTF-8'><title>Test</title></head>
    <body>
      <p>foo 1</p>
      <p>foo 2</p>
      <p>bar 1</p>
      <p>bar 2</p>
    </body>
  </html>`;

try {
  const [page] = await browser.pages();

  await page.goto(`data:text/html,${html}`);

  const ar = await page.$$("p");
  const shortArray = [];
  for (const element of ar) {
    const text = await (await element.getProperty("innerText")).jsonValue();
    console.log(text, text.includes("foo"));
    if (text.includes("foo")) shortArray.push(element);
  }
  console.log(shortArray.length);
  console.log('hello');

} catch(err) { console.error(err); } finally { await browser.close(); }
foo 1 true
foo 2 true
bar 1 false
bar 2 false
2
hello

推荐阅读