javascript - 如何在 JS 的 setInterval 中等待?

标签 javascript asynchronous promise async-await puppeteer

我有一个看起来像这样的代码段:

async function autoScroll(page, maxDate = null) {
  await page.evaluate(async () => {
    await new Promise(async (resolve, reject) => {
        try {
            const scrollHeight = document.body.scrollHeight;
            let lastScrollTop = 0;

            const interval = setInterval(async () => {
                window.scrollBy(0, scrollHeight);
                const scrollTop = document.documentElement.scrollTop;
                let lastDate = null;

                if (maxDate) {
                    const html = new XMLSerializer().serializeToString(document.doctype) + document.documentElement.outerHTML;

                    await extractDate(html).then((date) => {
                        lastDate = date;
                    });
                }

                if (scrollTop === lastScrollTop || 
                    (maxDate && lastDate && maxDate.getTime() >= lastDate.getTime())) {
                    clearInterval(interval);
                    resolve();
                } else {
                    lastScrollTop = scrollTop;
                }
            }, 2000);
        } catch (err) {
            console.error(err);
            reject(err.toString());
        }
    });
});
}

其中 extractDate 方法具有以下形式:

function extractDate(html) {
    return new Promise((resolve, reject) => {
        // Rest removed for brevity.
        resolve(result);
    });
}

现在的问题是,我的代码一直在滚动,但它不会等待 setInterval 中的其他内容完成,因为它会每 2 秒滚动一次,但通常 extractDate 函数应该花费超过 2 秒的时间,所以我实际上想等待 setInterval 中的所有内容完成,然后再调用新的间隔。

由于东西的异步性质,我没有设法 console.log 东西,所以要查看代码的行为。

那么,如何确保 setInterval 中的所有内容在进行下一次间隔调用之前完成?

编辑:

此解决方案使用 setTimeout 仅滚动一次并向 puppeteer 抛出未处理的 promise 拒绝错误。

 async function autoScroll(page, maxDate = null) {
     await page.evaluate(async () => {
        await new Promise(async (resolve, reject) => {
            try {
               const scrollHeight = document.body.scrollHeight;
               let lastScrollTop = 0;

                const interval = async function() {
                    window.scrollBy(0, scrollHeight);
                    const scrollTop = document.documentElement.scrollTop;
                    let lastDate = null;

                    if (maxDate) {
                        const html = new XMLSerializer().serializeToString(document.doctype) + document.documentElement.outerHTML;
                        await extractDate(html).then((date) => {
                            lastDate = date;
                        });
                    }

                    if (scrollTop === lastScrollTop || 
                       (maxDate && lastDate && maxDate.getTime() >= lastDate.getTime())) {
                        resolve();
                    } else {
                        lastScrollTop = scrollTop;
                        setTimeout(interval, 2000);
                    }
                }

                setTimeout(interval, 2000);

            } catch (err) {
                console.error(err);
                reject(err.toString());
            }
        });
    });
}

最佳答案

使用以下代码:

setInterval(async () => {
    await fetch("https://www.google.com/") 
}, 100);

关于javascript - 如何在 JS 的 setInterval 中等待?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51830200/

相关文章:

javascript - 我们如何使用 Cypress 验证元素即使存在于 DOM 中也不会显示

javascript - 如何删除大量数组中的重复条目(javascript)

c# - Web API 只允许单个异步任务

javascript - 确保带有异步调用的 forEach 在另一个调用之前执行?

javascript - 为什么这个 promise 会解决链中的第一项而不是最后一项?

javascript - 处理 promise 链中的多个捕获

javascript - 通过跨站点 AJAX 解释 JSONP

javascript - HTML 中消失的按钮

javascript - 将 html 标签和内容转换为字符串

javascript - 使用带有后文档就绪回调的 Jquery 异步获取多个脚本的正确方法