本文主要是介绍Puppeteer调用page对象evaluate方法产生的Execution context was destroyed错误处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Execution context was destroyed产生的场景
在NodeJs中使用Puppeteer中Page对象的evaluate方法执行脚本,深入使用后一定遇到过Error: Execution context was destroyed
错误。这通常发生在浏览器正在执行一个任务,紧接使用方并发提交了另一个脚本到浏览器,导致浏览器发生跳转。这时第一次提交的任务会抛出异常,产生该错误。
Execution context was destroyed 错误的解决
分析原因后可知问题在于调用方并发提交任务速度过快,而单独的一个浏览器对象执行脚本的QPS过低,导致出现该问题。那么此时可以通过多个打开过个Page对象(browser.newPage())来完成多任务执行,以避免产生该错误。而多个page对象的管理就需要用到对象池。 可以考虑使用node.js中流行的对象池工具generic-pool[1]
pagePool.use(async (page)=> {return await page.evaluate(page);});
在创建对象池时,对象数量需要根据实际业务情况来设置。比如实际业务需要执行脚本,执行时间期望小于500ms,那么为了达到6qs,则只要需要3个page对象(即三个浏览器窗口)。
为了保证任务执行时间限制在500ms内,执还需要进行超时判断。这时利用Promise.race方法来间接实现page.evaluate方法超时功能。
Promise.race([page.evaluate(data),page.waitFor(timeout)]);
最后在执行完一段脚本后,需要重新初始浏览器窗口环境,防止有定时任务之类的未知脚本一直执行占用资源,最终导致系统CPU利用率持续升高,无法正常使用。通过跳转到空白页即可实现。
page.goto("about:blank");
经过上述三步改造后最终可实现一个高效可用的evaluate方法,并保证提交的任务正常执行。如果单机无法满足条件,水平扩展机器即可。
参考
[1].generic-pool文档,https://www.npmjs.com/package/generic-pool
这篇关于Puppeteer调用page对象evaluate方法产生的Execution context was destroyed错误处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!