我有一个看起来像这样的代码段:
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/