Puppeteer - 如何在 setTimeout 内 return 结果 page.evaluate

Puppeteer - how to return a result in page.evaluate within setTimeout

我正在用 puppeteer 向底部滚动页面,当我按下一个键时,我想退出函数结束 return 结果。

脚本几乎可以工作,除了我无法 return 值和脚本结尾。

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({
                                            headless: false,
                                            userDataDir: "C:\Users\johndoe\AppData\Local\Google\Chrome\User Data\Default"
                                        });
  const page = await browser.newPage();
  await page.setViewport({
    width: 1920,
    height: 1080,
    deviceScaleFactor: 1,
  });
  await page.goto('https://www.facebook.com/groups/0000000/members',{waitUntil: 'networkidle0'});
  
  
  let rawMembers = await page.evaluate(() => { 

    const intervall = 3000;
    let stop = false;
    document.addEventListener('keypress', e => stop = true);  //press a key to exit

    let results = [];
    let i = 0;
    let pageHeigth = 0;
    let timerId = setTimeout(function tick() {

      if ((stop === false) && (document.body.scrollHeight > pageHeigth)){

        pageHeigth = document.body.scrollHeight  //save the current page heigth
        document.scrollingElement.scrollTop = pageHeigth;  //move the scroll to the end of the page (page visible size), this will couse new content to be loaded - virtula scroll)

        results.concat(pageHeigth);  //<--- it should be the results 

        timerId = setTimeout(tick, intervall);  //schedule a new timeout to repeat the function
      } 
      else
      {
        clearTimeout(timerId)
        return results;
      }

    }, intervall);
  });
  console.log('END')
  //await browser.close();
})();

concat方法return给你一个新数组。它没有修改现有数组。当您调用 concat 方法时,您需要将其分配给一个变量。所以这可能会解决问题

results.concat(pageHeight) //instead of this

let finalResult = results.concat(pageHeight) // you need to do this

您的 results 数组的其他方式始终为空,因为 concat 方法不会修改数组。 这是文档。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat#return_value

最后你需要 return finalResult 而不是 results

你可以 return 一个 Promise 并在计时器终止时解决它(另外,正如另一个答案中提到的,concat() 在这里不适合,你可以使用 push 代替) :

const rawMembers = page.evaluate(() => new Promise((resolve) => {
  const intervall = 3000;
  let stop = false;
  document.addEventListener('keypress', () => { stop = true; });

  const results = [];
  let pageHeigth = 0;
  let timerId = setTimeout(function tick() {
    if (stop === false && document.body.scrollHeight > pageHeigth) {
      pageHeigth = document.body.scrollHeight;
      document.scrollingElement.scrollTop = pageHeigth;

      results.push(pageHeigth);

      timerId = setTimeout(tick, intervall);
    } else {
      clearTimeout(timerId);
      resolve(results);
    }
  }, intervall);
}));