我想在while循环中添加一个delay/sleep:

我是这样试的:

alert('hi');

for(var start = 1; start < 10; start++) {
  setTimeout(function () {
    alert('hello');
  }, 3000);
}

只有第一种情况是正确的:在显示alert('hi')后,它将等待3秒,然后alert('hello')将显示,但随后alert('hello')将不断重复。

我想要的是,在警报('hello')显示3秒后警报('hi'),然后它需要等待3秒的第二次警报('hello'),以此类推。


当前回答

const autoPlayer = (arr = [1, 2, 3, 4, 5]) => {
  // Base case:
  if (arr.length < 1) return

  // Remove the first element from the array.
  const item = arr.shift()

  // Set timout 
  setTimeout(() => {
    console.log('Hello, world!', item)  // Visualisation.
    autoPlayer() // Call function again.
  }, 1000) // Iterate every second.
}

Hey, I know this post is very old, but this code "loops" and adds a delay to it using a recursive method. I don't think you can 'actually' delay a loop itself from iterating based on reading various comments from other people. Maybe this can help someone out! Basically the function accepts an array (in this example). On each iteration the setTimeout Javascript method is called. The function calls itself again indefinitely when the timer of the setTimeout function expires, but on each call the array becomes smaller until it reaches the base-case. I hope this can help anyone else out.

其他回答

我只是想在这里发表我的意见。此函数运行具有延迟的迭代循环。请看这个jsfiddle。函数如下:

function timeout(range, time, callback){
    var i = range[0];                
    callback(i);
    Loop();
    function Loop(){
        setTimeout(function(){
            i++;
            if (i<range[1]){
                callback(i);
                Loop();
            }
        }, time*1000)
    } 
}

例如:

//This function prints the loop number every second
timeout([0, 5], 1, function(i){
    console.log(i);
});

相当于:

//This function prints the loop number instantly
for (var i = 0; i<5; i++){
    console.log(i);
}

您可以创建一个承诺setTimeout的睡眠函数。这使您可以使用async/await来编写代码,而无需回调和熟悉的for循环控制流。

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); (async () => { 对于(设I = 0;I < 10;我+ +){ console.log(我); 等待睡眠(1000); } console.log(“完成”); }) ();

在Node中,你可以使用计时器/承诺来避免承诺步骤(如果旧版本的Node不支持该功能,上面的代码也可以工作):

const {setTimeout: sleep} = require("timers/promises");

// same code as above

无论如何,由于JS是单线程的,超时是异步的是一件好事。如果不这样做,浏览器就没有机会重新绘制UI,从而导致用户的界面冻结。

非常简单的单行解决方案,具有实际的异步等待延迟(没有排队setTimeout):

下面的(自动执行匿名)函数在循环之间创建一个实际的延迟,而不是具有不同超时的多个settimeout,这可能会弄乱内存。

在100个循环中的每一个循环中,它都等待一个新的承诺来解决。 这只发生在setTimeout '允许'它在90ms后。在此之前,代码将被async-await / pending Promise阻塞。

(async () => { For(令i=0;我< 100;我+ +){ 等待新的承诺((resolve) => {setTimeout(() =>{文档。我写(“${}”);解决(true)}, 90)}); } })()

我用蓝鸟的承诺。延时和递归。

函数 myLoop(i) { 返回承诺延迟(1000) .then(function() { 如果 (i > 0) { 警报(“你好”); 返回 myLoop(i -= 1); } }); } 我的循环(3); <script src=“//cdnjs.cloudflare.com/ajax/libs/bluebird/2.9.4/bluebird.min.js”></script>

因为ES7有一个更好的方法来等待循环:

// Returns a Promise that resolves after "ms" Milliseconds
const timer = ms => new Promise(res => setTimeout(res, ms))

async function load () { // We need to wrap the loop into an async function for this to work
  for (var i = 0; i < 3; i++) {
    console.log(i);
    await timer(3000); // then the created Promise can be awaited
  }
}

load();

当引擎到达await部分时,它设置一个超时并停止async函数的执行。然后,当超时完成时,继续执行。这是非常有用的,因为你可以延迟(1)嵌套循环,(2)有条件的,(3)嵌套函数:

异步函数任务(i) {// 3 等待计时器(1000); console.log('任务${i}完成! '); } 异步函数main() { 对于(设I = 0;I < 100;I += 10) { For(令j = 0;J < 10;j++) {// 1 如果(j % 2) {// 2 等待任务(i + j); } } } } main (); 函数定时器(ms){返回新的承诺(res => setTimeout(res, ms));}

MDN参考资料

虽然ES7现在被NodeJS和现代浏览器支持,但你可能想用BabelJS编译它,这样它就可以在任何地方运行。