Playwright多页面异步执行异常求助:页面未并行运行
问题排查与修复建议
1. Promise.all 中误用 await 导致串行执行
你的代码中存在Promise.all 内部添加多余 await的问题,这直接导致原本期望并行的操作变成了串行执行:
// 错误写法:内部的 await 会先逐个执行函数,再将结果传入 Promise.all await Promise.all([ await goToPageAndGetToken(page1, `${baseURL}/bakery-manage`), await goToPageAndGetToken(page2, `${baseURL}/bakery-manage`), ])
这段代码的实际执行逻辑是:先等待page1的页面跳转完成,再执行page2的跳转,最后才把两个已完成的Promise传入Promise.all,完全失去了并行执行的意义。
修复方式:去掉Promise.all内部的await,直接传入异步函数调用(返回Promise):
// 正确写法:同时触发两个异步操作,并行执行 await Promise.all([ goToPageAndGetToken(page1, `${baseURL}/bakery-manage`), goToPageAndGetToken(page2, `${baseURL}/bakery-manage`), ])
2. 页面操作的隐性等待优化
虽然createProgram函数内部的操作是串行的(符合业务逻辑),但要确保Playwright的内置等待机制没有过度等待。可以检查以下几点:
- 确认
checkHidden、checkVisible等工具函数是否使用了合理的超时时间,避免不必要的长等待 - 确保
clickAddProgram、fillAddProgramItem等操作函数没有额外的强制等待(如page.waitForTimeout),这类硬等待会直接增加测试耗时
3. 上下文与页面的资源隔离
你当前使用同一个浏览器上下文创建两个页面,虽然Playwright支持上下文内多页面并行,但如果页面之间存在共享的会话状态(如token、缓存),可能会出现隐性的资源竞争或等待。如果上述修复后仍有串行问题,可以尝试为每个页面创建独立的上下文:
// 为两个页面分别创建独立上下文,彻底隔离资源 const context1 = await browser.newContext() const page1 = await context1.newPage() const context2 = await browser.newContext() const page2 = await context2.newPage()
4. 清理操作的并行优化
最后的删除操作部分,你将两个页面的删除和确认操作放在同一个Promise.all中,这里可以拆分为两组并行操作,进一步提升效率:
// 并行处理两个页面的删除流程 await Promise.all([ (async () => { await clickDeleteProgram(page1, testId) await confirmProgramDelete(page1, testId) })(), (async () => { await clickDeleteProgram(page2, testId1) await confirmProgramDelete(page2, testId1) })() ])
这样每个页面的删除+确认操作内部串行,两个页面之间并行,比原来把四个操作放在一起更符合逻辑,也能避免潜在的时序问题。
内容的提问来源于stack exchange,提问作者Alice Rossi
相关产品推荐
相关产品推荐

