简体   繁体   中英

await does not work as expected inside a loop when the code is executed by puppeteer - but it works perfectly when run in browser's console

I am evaluating codeToBeEvaluated function in browser using puppeteer . codeToBeEvaluated has a while loop which is supposed to show an alert (see LINE B) after every 10s.

The problem is when I run this script, I don't see any alerts. Code execution doesn't wait for 10s in Line A. Rather process exits immediately. I have no idea why. I am really curious why it's not working.

Interestingly, when I run only the codeToBeEvaluated function in the browser's console, it works perfectly fine and I see the alerts that I am supposed to see.

It would be awesome if someone could explain this behaviour. I am not looking for any workarounds to show up alerts. I just want to understand this behaviour.

const puppeteer = require("puppeteer");


// this function will be executed in the browser
// it should create an alert after some time interval
const codeToBeEvaluated = async () => {
  let index_2 = 0;

  // a promise that resolves after ms*1000 seconds
  async function sleep(ms) {
    return new Promise((resolve) => {
      setTimeout(resolve, ms);
    });
  }

  // await within function's while loop
  async function whileWrapper() {
    while (index_2 < 10) {
      await sleep(10000); // LINE A: execution doesn't stop at all :/
      alert("hello " + index_2); // LINE B: does NOT execute at all
      index_2++;
    }
  }

  whileWrapper();
};

async function main(url) {
  const browser = await puppeteer.launch({
    // headless: false,
    devtools: true,
    // args: ["--no-sandbox", "--disable-setuid-sandbox"],
  });
  const page = await browser.newPage();

  await page.goto(url);

  await page.evaluate(codeToBeEvaluated);

  browser.close();
}

main("https://www.google.com/search?q=hello");

the reason for the difference between executing codeToBeEvaluated on DevTools manually vs. from your puppeteer script is that:

  • on DevTools console the script has infinite time to execute a longer async command (except if you are quickly closing the browser while it is still running)
  • in your puppeteer script you have other commands following the page.evaluate like browser.close (which I advise you to put after an await as it returns a promise,), so the browser is closed before the function would finish

you need to await whileWrapper() 's promise too, so changing your code in LINE 25 to the following will make it behave as you would have expected:

  await whileWrapper();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM