如何在 JavaScript 循环中添加延迟?

新手上路,请多包涵

我想在 while 循环中添加延迟/睡眠:

我试过这样:

alert('hi');

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

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

我想要的是在 alert('hello') 之后 3 秒显示 alert('hi') 然后它需要等待 3 秒第二次 alert('hello') 等等。

原文由 olidev 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.7k
2 个回答

setTimeout() 函数是非阻塞的,将立即返回。因此,您的循环将非常快速地迭代,并且它将快速连续地启动 3 秒超时触发器。这就是为什么您的第一个警报会在 3 秒后弹出,然后所有其他警报都会连续出现,没有任何延迟。

您可能想改用这样的东西:

 var i = 1; // set your counter to 1

 function myLoop() { // create a loop function
 setTimeout(function() { // call a 3s setTimeout when the loop is called
 console.log('hello'); // your code here
 i++; // increment the counter
 if (i < 10) { // if the counter < 10, call the loop function
 myLoop(); // .. again which will trigger another
 } // .. setTimeout()
 }, 3000)
 }

 myLoop(); // start the loop

您还可以通过使用自调用函数来整理它,将迭代次数作为参数传递:

 (function myLoop(i) {
 setTimeout(function() {
 console.log('hello'); // your code here
 if (--i) myLoop(i); // decrement i and call myLoop again if i > 0
 }, 3000)
 })(10); // pass the number of iterations as an argument

原文由 Daniel Vassallo 发布,翻译遵循 CC BY-SA 4.0 许可协议

由于 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 function 。然后,当超时完成时,执行会在该点继续。这非常有用,因为您可以延迟 (1) 嵌套循环,(2) 有条件地,(3) 嵌套函数:

 async function task(i) { // 3
  await timer(1000);
  console.log(`Task ${i} done!`);
}

async function main() {
  for(let i = 0; i < 100; i+= 10) {
    for(let j = 0; j < 10; j++) { // 1
      if(j % 2) { // 2
        await task(i + j);
      }
    }
  }
}

main();

function timer(ms) { return new Promise(res => setTimeout(res, ms)); }

参考 MDN

虽然 ES7 现在受到 NodeJS 和现代浏览器的支持,但您可能希望使用 BabelJS 对其进行转换,以便它可以在任何地方运行。

原文由 Jonas Wilms 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏