setTimeout в Promise - как решить и почему он запускается только один раз? - PullRequest
0 голосов
/ 13 апреля 2019

Я хотел бы смоделировать прокрутку мыши на основе случайного времени с помощью setTimeout в Promise. Моя цель состоит в том, чтобы продолжать прокручивать страницу до самого дна: функцию автопрокрутки нужно вызывать несколько раз, пока она не достигнет дна, затем разрешите Обещание. В настоящее время код выполняется только один раз, затем я получил 2 ошибки: Uncaught ReferenceError: loopScroll не определен (в консоли браузера) UnhandledPromiseRejectionWarning (в VSCode).

async function loopScroll(page) { 
    await page.evaluate(async () => {
        await new Promise((resolve, reject) => {
            let rand = Math.round(Math.random() * (3000 - 500)) + 500;
            setTimeout(function () {
                function autoScroll() {
                    let scrollHeight = document.body.scrollHeight;
                    let currentHeight = 0;
                    let distance = 100;
                    window.scrollBy(0, distance);
                    currentHeight += distance;
                    if (currentHeight >= scrollHeight) {
                        resolve();
                    }
                }
                autoScroll();
                loopScroll(page);
            }, rand);
        });
    });
};

Эта асинхронность - обещание немного сбивает меня с толку, у меня не слишком много опыта с ними, поэтому я действительно не знаю, что я делаю неправильно. Заранее спасибо.

1 Ответ

1 голос
/ 13 апреля 2019

Как уже упоминалось в комментариях, первая проблема здесь заключается в том, что эта часть кода выполняется в среде NodeJS:

 async function loopScroll(page) { 
   await page.evaluate(/* page environment */);
 }

и там, где определено loopScroll, среда страниц не имеет доступак этой функции.Вот почему вызов loopScroll не удался и завершает исключение.

Поскольку вы уже используете async / await, вам вообще не нужно использовать рекурсию, просто await цикл:

 await page.evaluate(async () => {
  const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

  let scrollHeight = document.body.scrollHeight;
  let currentHeight = 0;
  let distance = 100;

  while(true) {
    let rand = Math.round(Math.random() * (3000 - 500)) + 500;

    window.scrollBy(0, distance);
    currentHeight += distance;
    if (currentHeight >= scrollHeight) {
         break;
    }

   await delay(rand);
 }
});
...