在继续下一行之前等待 N 秒

木偶师中,我希望在进入下一行代码之前等待一段确定的时间。

我尝试在一个求值函数中放入一个 setTimeout,但它似乎被简单地忽略了

console.log('before waiting');
await page.evaluate(async() => {
setTimeout(function(){
console.log('waiting');
}, 4000)
});
console.log('after waiting');

这段代码不需要等待,只需要编写 在等待之前在等待之后

你知道怎么做吗?

179866 次浏览

你的语法不完整。
试试这个..

await page.evaluate(async() => {
setTimeout(function(){
console.log('waiting');
}, 4000)
});

你可以使用一个承诺函数,

function delay(time) {
return new Promise(function(resolve) {
setTimeout(resolve, time)
});
}

那么,如果你想延迟的话就打电话吧。

console.log('before waiting');
await delay(4000);
console.log('after waiting');

如果必须使用木偶师,请使用内置的 watiForTimeout 函数。

await page.waitForTimeout(4000)

如果您仍然希望使用 page.value,请在4秒后解析它。

await page.evaluate(async() => {
await new Promise(function(resolve) {
setTimeout(resolve, 1000)
});
});

但是我想您可以简单地使用前两个例子。

对于 wait for one second,可以使用下列选项之一:

await page.waitFor(1000);
await frame.waitFor(1000);
await new Promise(r => setTimeout(r, 1000));

另外,还有许多木偶师函数,其中包括一个内置的 delay选项,它可能会派上用场,以便在某些事件之间等待:

// Click Delay
// Time to wait between mousedown and mouseup in milliseconds. Defaults to 0.


await page.click('#example', {delay: 1000});
await frame.click('#example', {delay: 1000});
await elementHandle.click({delay: 1000});
await page.mouse.click(0, 0, {delay: 1000});


// Type Delay
// Time to wait between key presses in milliseconds. Defaults to 0.


await page.type('#example', 'Hello, world!', {delay: 1000});
await frame.type('#example', 'Hello, world!', {delay: 1000});
await elementHandle.type('Hello, world!', {delay: 1000});
await page.keyboard.type('Hello, world!', {delay: 1000});


// Press Delay
// Time to wait between keydown and keyup in milliseconds. Defaults to 0.


await elementHandle.press('Backspace', {delay: 1000});
await page.keyboard.press('Backspace', {delay: 1000});
await new Promise(_func=> setTimeout(_func, 5000));

试试这个功能。

function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}

使用它

  async function demo() {
console.log('Waiting...');
await sleep(3000);
console.log('ok');
}


demo();

我一直在用:

await page.waitForTimeout(3000);

3000毫秒在哪里 这对我来说似乎很有效。

其他的答案已经显示了如何睡觉,但是现在 page.waitForTimeoutfinally deprecated,我想我应该加上一个我一直想加的答案:

别睡!它会导致一个竞态条件,干扰人偶师的事件驱动特性,引入不必要的脆性。几乎总有一个更好的预测值得等待:

  • 您正在等待选择器出现吗? 请尝试 waitForSelector
  • 您正在等待 XPath 出现吗? 请尝试 waitForXPath
  • Are you waiting for a navigation? Try waitForNavigation.
  • 您在等待网络响应吗? 请尝试 waitForNetworkIdlewaitForResponse
  • 你在等待一个弹出窗口吗? 试着承诺 .on("dialog", ...
  • 您是否在等待一些任意的谓词,比如出现最少数量的子元素? 请尝试 waitForFunction
  • 还有别的事吗?运行一个 evaluate块并添加您自己的代码,以等待与 setIntervalrequestAnimationFrame的 DOM 突变或轮询,并根据您的需要有效地重新实现 waitForFunction

特别是 waitForFunction没有得到充分利用,但它增加了大量的可靠性和精度,而 waitForTimeout没有。

If all else fails and you have to block the script, you can delay, but I've written hundreds of Puppeteer scripts and have never had to use any sleep variant, so I'm pretty convinced it's basically unnecessary.

请参阅 我关于木偶师反模式的博客文章以获得更多关于为什么你应该避免以任何形式睡觉的分析,除非作为绝对的最后手段。