【问题标题】:Puppeteer promisifying an event, is this proper event control flow?Puppeteer 承诺一个事件,这是正确的事件控制流程吗?
【发布时间】:2020-01-23 12:22:34
【问题描述】:

我正在尝试在使用 puppeteer 时获取下载文件的名称,并且我进行了以下设置,但我想知道如何最好地将 removeListener 用于 page.on('response', ...,因为我希望能够设置并在每次下载文件时取消设置此事件:

async (page) => {
  const form = await page.$('#selector');
  const [filename] = await Promise.all([
    getFileNamePromise(page),
    form.evaluate(form => form.submit())
  ]) 
  return filename;
};

function getFileNamePromise(page) {
  return new Promise (resolve => {
    page.on('response', response => {
      const disposition = response.headers()['content-disposition'];

      if (disposition && disposition.indexOf('attachment') !== -1) {
        var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
        var matches = filenameRegex.exec(disposition);
        if (matches != null && matches[1]) { 
          resolve(matches[1].replace(/['"]/g, '')) ;
        }
      }
    })
  });
}

我也很好奇这是否会受到在加载事件侦听器之前下载文件的竞争条件的影响?

【问题讨论】:

  • 你是指删除page.on('response'...的监听器吗?
  • @LonnieBest 是的 - 我更新了问题。

标签: javascript promise dom-events puppeteer


【解决方案1】:

转到文档中的here

在第一个代码示例之后说:

Page 类发出各种事件(如下所述),这些事件可以是 使用任何 Node 的本机 EventEmitter 方法处理,例如 on, 一次或 removeListener。

稍后它会这样说,然后是一个代码示例:

要取消订阅事件,请使用 removeListener 方法:

function logRequest(interceptedRequest) {
  console.log('A request was made:', interceptedRequest.url());
}
page.on('request', logRequest);
// Sometime later...
page.removeListener('request', logRequest);

所以我假设你可以效仿page.removeListener('response'...

至于你问题的比赛条件部分,我没有足够的 Puppeteer 经验给你一个权威的答案。对我来说,您似乎总是能够比响应发生的更快地设置事件侦听器,因为当响应添加到事件队列时,设置事件侦听器的代码已经在事件循环中.不过,我不确定。

【讨论】:

    【解决方案2】:

    谢谢,我最终添加了 removeListener 作为与解决承诺相关的逻辑的一部分。如下:

    page.on('response', function getFileNameFromRequest(response) {
      //check for "Content-Disposition" ?
      const disposition = response.headers()['content-disposition'];
    
      if (disposition && disposition.indexOf('attachment') !== -1) {
        var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
        var matches = filenameRegex.exec(disposition);
        if (matches != null && matches[1]) { 
          resolve(matches[1].replace(/['"]/g, ''));
          page.removeListener("response", getFileNameFromRequest);
        }
      }
    });
    

    【讨论】:

      猜你喜欢
      • 2015-09-29
      • 2014-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-30
      • 2017-12-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多