Обход нескольких URL-адресов в цикле с использованием кукловода
У меня
urls = ['url','url','url'...]
это то, что я делаю
urls.map(async (url)=>{
await page.goto(`${url}`);
await page.waitForNavigation({ waitUntil: 'networkidle' });
})
Это, похоже, не дожидается загрузки страницы и быстро набирает все URL-адреса (я даже пытался использовать page.waitFor)
просто хотел знать, что я делаю что-то принципиально неправильное или этот тип функциональности не рекомендуется/поддерживается
Ответы
Ответ 1
map
, forEach
, reduce
и т.д. не ждут асинхронной операции внутри них, прежде чем перейти к следующему элементу итератора, который они выполняют итерацию.
Существует несколько способов одновременного прохождения каждого элемента итератора при выполнении асинхронной операции, но самый простой в этом случае, я думаю, будет просто использовать обычный оператор for
, который ждет завершения операции.
const urls = [...]
for (let i = 0; i < urls.length; i++) {
const url = urls[i];
await page.goto(`${url}`);
await page.waitForNavigation({ waitUntil: 'networkidle' });
}
Это будет посещать один URL за другим, как вы ожидаете. Если вам любопытно повторить итерацию с помощью await/async, вы можете заглянуть в этот ответ: fooobar.com/questions/44161/...
Ответ 2
Если вы обнаружите, что ожидаете своего обещания бесконечно, предлагаемое решение заключается в следующем:
const urls = [...]
for (let i = 0; i < urls.length; i++) {
const url = urls[i];
const promise = page.waitForNavigation({ waitUntil: 'networkidle' });
await page.goto('${url}');
await promise;
}
Как указано в этом выпуске github