如何在Puppeteer中定时截图后正常关闭浏览器避免僵尸进程?
问题分析
问题出在getScreenshots的实现逻辑上:当执行resolve(promises)返回结果时,数组中的截图Promise可能还处于Pending状态(截图操作尚未完成),此时await getScreenshots会直接进入后续流程,finally块关闭浏览器时,正在执行的截图操作会因为浏览器实例被销毁而抛出错误。
解决方案
修改getScreenshots,确保所有截图操作完成后再返回结果;同时在合适时机关闭页面,避免资源泄漏。
改写后的完整代码
const getScreenshots = async (browser, url, ms, frames): Promise<string[]> => { const page = await browser.newPage() await page.setViewport({ width: 1280, height: 800 }) await page.goto(url, { waitUntil: "networkidle0", }) const promises: Promise<string>[] = [] return new Promise((resolve) => { const intervalId = setInterval(() => { // 将截图Promise存入数组 promises.push( page.screenshot({ captureBeyondViewport: true, fullPage: true, encoding: "base64", }) ) if (promises.length >= frames) { clearInterval(intervalId) // 等待所有截图Promise完成后再返回结果,同时关闭页面 Promise.all(promises) .then(async (results) => { await page.close() resolve(results) }) } }, ms) }) } const screenshotTest = async (url: string): Promise<string> => { const browser = await puppeteer.launch({ timeout: 100000 }) try { const imgArray = await getScreenshots(browser, url, 42, 24) return imgArray[imgArray.length - 1] } finally { await browser.close() } }
关键修改点
- 等待所有截图完成:将
resolve(promises)改为Promise.all(promises).then(...),确保所有异步截图操作执行完毕后才返回结果,此时await getScreenshots会等待所有截图完成,再进入finally块关闭浏览器。 - 及时关闭页面:在所有截图完成后关闭页面
page.close(),避免页面实例占用资源。 - 类型优化:移除了
imgArray: any[]的冗余类型声明,让TypeScript自动推导类型更严谨。
这样修改后,既不会出现僵尸进程,也不会因为提前关闭浏览器导致截图失败。
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

