Кукловод, обещающий событие, это правильный поток управления событиями? - PullRequest
0 голосов
/ 22 января 2020

Я пытаюсь получить имя загруженного файла при использовании 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, '')) ;
        }
      }
    })
  });
}

Мне также любопытно, будет ли это восприимчиво к состоянию гонки, когда файл загружается до загрузки прослушивателя событий?

Ответы [ 2 ]

1 голос
/ 22 января 2020

Go здесь в документации.

После того, как первый пример кода говорит:

Класс Page генерирует различные события (описанные ниже) который может быть обработан с использованием любого из собственных методов EventEmitter узла, таких как on, once или removeListener.

Позже это говорит об этом, сопровождаемый примером кода:

To Отказаться от участия в мероприятиях используйте метод 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, чтобы дать вам авторитетный ответ. Мне кажется, что вы всегда сможете установить прослушиватель событий быстрее, чем может произойти ответ, потому что этот код, который устанавливает прослушиватель событий, будет в событии -l oop уже при добавлении ответа в Очередь событий. Однако я не уверен.

0 голосов
/ 23 января 2020

Спасибо, в итоге я добавил removeListener как часть логики c, связанной с разрешением обещания. Следующим образом:

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);
    }
  }
});
...