You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 10:05:55