我在一个文件夹中有一组具有特定名称的文件,我使用 Node 返回这些文件的名称,然后对于每个文件,我想运行一个 puppeteer 测试来填充表单并提交它,但我似乎forEach 遇到问题,没有等待上一个测试完成,最终导致加载执行上下文被破坏
,这显然阻止了我的测试完成。我最终发现用户已登录,但在某些情况下 page.type
页面未运行...
如何等待 puppeteer 完成测试,然后运行 forEach 中的下一个元素?
参见下面的代码:
fs.readdir(testFolder, async (err, files) => {
files.forEach(file => {
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
page.setViewport({
width: 1920,
height: 1080
});
await page.goto('www.mypage.com');
//login
// some login code here
await page.click('#register')
await page.waitForNavigation();
console.log('New Page URL:', page.url());
await page.waitForSelector('#firstName');
await page.waitFor(1000);
await page.type('#firstName', file);
// register and wait for nagivation (in my case it is a page reload)
await page.waitForSelector('#updateProfile');
await page.click('#updateProfile');
await page.waitForNavigation();
await browser.close();
})();
});
});
最佳答案
将 Array.forEach 与 async/await 一起使用是一个棘手的问题,因为所有迭代器都将被执行,但 forEach 将在所有迭代器完成执行之前返回,这不是理想的情况在许多情况下,异步函数的行为。
查看 map 、forEach 和 for...of here 中 puppeteer 点击的基准测试,它给出了发生的情况的图片。
解决方案
I.) 当您迭代主 puppeteer 脚本时,我可以通过将 forEach
重构为 for...of
循环来解决它, 它会导致性能稍差,因为执行是按照严格的顺序而不是并行进行的,但它仍然符合您的期望:
wait for the puppeteer to complete the test and then run the next element
II.)或者您可以创建自己的“async forEach”方法。
例如:
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array)
}
}
asyncForEach 方法的来源:Sebastien Chopin: JavaScript: async/await with forEach() (codeburst.io)
关于node.js - forEach 中的 Puppeteer 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62873411/