Вы уже дали решение, но так как это общая проблема с библиотекой (я - автор I), я хотел бы предоставить некоторые дополнительные сведения.
Как работает функция задачи
Когда задание ставится в очередь и готово к выполнению, puppeteer-cluster создаст страницу и вызовет функцию задачи (заданную для cluster.task
) с созданным объектом page
и данными в очереди.,Затем кластер ожидает, пока Обещание не будет выполнено (выполнено или отклонено), и закроет страницу и выполнит следующее задание в очереди.
Поскольку асинхронная функция неявно создает Обещание, это означает, что как толькоАсинхронная функция, заданная для функции 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
, поскольку библиотека не может перехватывать события, генерируемые внутри блоков асинхронного кода.