即便使用await,监听代码和主程序代码也是异步的,现在有个需求是捕捉alert提示,如果监听到alert,就返回alert信息,否则返回 success,一开始是如下设计:
这样不行,因为监测到alert信息后,当执行监听内返回代码的时候,报出错误 Cannot set headers after they are sent to the client,因为上面的return已经先返回了,麻烦大神帮忙看看,这种情况要怎么设计才能实现需求啊?自己折腾好久,也还是实现不了需求!!!~~~
首先page.goto(loginUrl)的方法返回了什么的,其次,如果dialog事件代表的失败,是否还有另外一个事件表示成功,后者的话,可以通过同时监听成功的事件返回。前者,是否能通过page.goto(loginUrl)返回的数据进行是否成功判断,从而不用另外监听dialog事件。
@heguangda 谢谢回复,page.goto什么也不返回,就是跳转一个网页,跳转成功后,有肯能会捕捉到alert,监听是必须的,因为alert是随机触发的…因为监听和主程序是并行执行的,所以会导致上图错误~~~现在有一点我不太明白,既然已经有一个return已经执行了,不就代表这次路由访问结束了么?为什么监听里还会执行一次return
@index-js 谢谢回复,能给个思路么?page.once 我不会封装,page.once ,里面的代码已经是await形式的了啊
async function main() {
const res = await gotoWrapper(page);
// ...
return res;
}
function gotoWrapper(page) {
return new Promise(async resolve => {
// 此时代表goto失败
page.on('dialog', () => {
resolve({ status: 'error', codeMsg: -101 });
});
await page.goto(loginUrl, { timeout: 8000 });
resolve({ status: 'success' });
});
}
建议需要复习下 Promise 和 callback 的区别
@iori2882, 先回答你的一个疑问:
既然已经有一个return已经执行了,不就代表这次路由访问结束了么?为什么监听里还会执行一次return
因为那你写的代码内存泄漏了,而且是典型的内存泄漏,你新增了一个监听器,却没有取消监听(once表示执行一次回调函数才取消监听),你应该在return之前把监听器取消掉。 其次你写的代码还有问题,代码看上去像是自动化测试,恰巧之前我写过自动化测试。page.goto指的是跳往新的页面,你这里应该给个超时时间,因为页面加载是需要时间的,保守估计,给个5秒,如果5秒内没有监听到alert事件,就返回success,否则返回错误
@yuezm 谢谢你的耐心回复,还打了一段示例代码,十分感谢,现在的问题是,即便向您这么写,gotoWrapper方法里的page.on也是单独进程的,可发生如下情况:还没等捕捉alert的时候,resolve({ status: ‘success’ })已经先执行了,这样就错过捕捉alert 了,我的想法是有没有办法让page.on变成同步的,就是执行page.on的时候,其他代码不执行
@zhoushoujian 嗯 事实确实如此,我用的是谷歌的puppeteer自动化测试,这个page.on是谷歌提供的方法,我并没有找到停止这个监听的方法!在GitHub上isuse也得不到回复~~