木偶操纵者(群集)在我与其交互时关闭页面 [英] Puppeteer (Cluster) closing page when I interact with it

查看:22
本文介绍了木偶操纵者(群集)在我与其交互时关闭页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在NodeJS v10.x.x环境中,尝试从一些HTML代码创建PDF页面时,每次尝试使用它(setCacheEnabled、setRequestInterception.)时都会遇到关闭页面的问题:

async (page, data) => {
  try {
    const {options, urlOrHtml} = data;
    const finalOptions = { ...config.puppeteerOptions, ...options };

    // Set caching flag (if provided)
    const cache = finalOptions.cache;
    if (cache != undefined) {
      delete finalOptions.cache;
      await page.setCacheEnabled(cache); //THIS LINE IS CAUSING THE PAGE TO BE CLOSED
    }

    // Setup timeout option (if provided)
    let requestOptions = {};
    const timeout = finalOptions.timeout;
    if (timeout != undefined) {
      delete finalOptions.timeout;
      requestOptions.timeout = timeout;
    }

    requestOptions.waitUntil = 'networkidle0';
    if (urlOrHtml.match(/^http/i)) {
      await page.setRequestInterception(true); //THIS LINE IS CAUSING ERROR DUE TO THE PAGE BEING ALREADY CLOSED
      page.once('request', request => {

        if(finalOptions.method === "POST" && finalOptions.payload !== undefined) {
          request.continue({method: 'POST', postData: JSON.stringify(finalOptions.payload)});
        }
      });

      // Request is for a URL, so request it
      await page.goto(urlOrHtml, requestOptions);
    }

    return await page.pdf(finalOptions);
  } catch (err) {
    logger.info(err);
  }
};

我在某处读到此问题可能是由于等待丢失的某些内容造成的,但这看起来不像我的情况。

我不是直接使用puppeteer,而是这个在其上创建集群并处理进程的库:

https://github.com/thomasdondorf/puppeteer-cluster

推荐答案

您已经给出了解决方案,但由于这是库的常见问题(我是作者🙂),我想提供一些更多见解。

任务函数的工作原理

当作业排队并准备执行时,puppeteer-cluster将创建一个页面,并使用创建的page对象和排队的数据调用任务函数(赋予cluster.task)。然后,群集等待承诺完成(已履行或已拒绝),并将关闭该页并执行队列中的下一个作业。

因为异步函数正在隐式创建承诺,这意味着赋予cluster.task函数的异步函数一完成,页面就会关闭。不会发生任何神奇的事情来确定该页面是否可能在将来使用。

正在等待异步事件

下面是一个带有常见错误的代码示例。用户可能希望在关闭页面之前等待外部事件,如下面的(不工作)示例所示:

非工作(!)代码示例:

await cluster.task(async ({ page, data }) => {
    await page.goto('...');
    setTimeout(() => { // user is waiting for an asynchronous event
        await page.evaluate(/* ... */); // Will throw an error as the page is already closed
    }, 1000);
});

在此代码中,在执行异步函数之前页面已经关闭。若要正确执行此操作,应改为返回承诺。

工作代码示例:

await cluster.task(async ({ page, data }) => {
    await page.goto('...');

    // will wait until the Promise resolves
    await new Promise(resolve => {
        setTimeout(() => { // user is waiting for an asynchronous event
            try {
                await page.evalute(/* ... */);
                resolve();
            } catch (err) {
                // handle error
            }
        }, 1000);
    });
});

在此代码示例中,任务函数等待,直到解析内部承诺,直到它解析该函数。这将使页面保持打开状态,直到异步函数调用resolve。此外,代码使用try..catch挡路,因为库无法捕获异步代码块内引发的事件。

这篇关于木偶操纵者(群集)在我与其交互时关闭页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆