调用Puppeteer异步拦截函数时无需使用await的解决方案
问题解决思路
你遇到的无限等待问题,核心原因有两个:
- 函数内部存在未定义变量
data,调用interceptedRequest.continue(data)时会抛出错误; - 调用异步函数时未处理返回的Promise,未捕获的错误会扰乱Node.js事件循环,进而阻塞
page.setRequestInterception(true)的异步操作。
第一步:修复函数内部的错误
拦截器代码里的data是未定义的,会直接触发错误。如果不需要修改请求内容,直接调用无参的continue()即可;如果需要修改请求,要先定义合法的data对象:
module.exports.basketPosterInterceptor = async ({ page, currentPrice }) => { const postRequestPrice = currentPrice * 1000 * 1000; await page.setRequestInterception(true); logger.info(`Poster enable price: ${postRequestPrice}`); page.on('request', (interceptedRequest) => { // 不需要修改请求时,直接调用continue() interceptedRequest.continue(); // 如果需要修改请求(比如替换价格),示例代码: // const originalPostData = interceptedRequest.postData() ? JSON.parse(interceptedRequest.postData()) : {}; // const modifiedPostData = { ...originalPostData, price: postRequestPrice }; // interceptedRequest.continue({ // postData: JSON.stringify(modifiedPostData) // }); }); };
第二步:让函数在后台运行且避免阻塞
不能直接去掉await就不管,必须处理异步函数返回的Promise,确保错误被捕获,同时不阻塞主线程。有两种常用方式:
方式1:用自执行异步函数包裹
// 自执行异步函数,后台运行拦截器 (async () => { try { await puppeteerService.basketPosterInterceptor({ page: posterPage, currentPrice: 50 }); } catch (err) { logger.error("拦截器启动失败", err); } })();
方式2:用void忽略Promise并捕获错误
// 用void表示不需要等待Promise完成,同时用catch捕获错误 void puppeteerService.basketPosterInterceptor({ page: posterPage, currentPrice: 50 }).catch(err => { logger.error("拦截器启动失败", err); });
这样处理后,拦截器会在后台异步初始化,既不需要await阻塞主线程,也不会因为未处理的错误导致setRequestInterception无限等待。
内容的提问来源于stack exchange,提问作者Tolgay Toklar
相关产品推荐
相关产品推荐

