Обход нескольких 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