我想在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'),以此类推。


当前回答

在ES6 (ECMAScript 2015)中,您可以使用生成器和间隔迭代延迟。

生成器(generator)是ECMAScript 6的一个新特性,是可以被替换的函数 顿了顿,接着说。调用genFunc不会执行它。相反,它 返回一个所谓的生成器对象,让我们控制genFunc的 执行。genFunc()最初是挂起在它的开始 的身体。方法genObj.next()继续执行genFunc, 直到下一次丰收。 (探索ES6)

代码示例: Let arr = [1,2,3, 'b']; let genObj = genFunc(); let val = genObj.next(); console.log (val.value); let interval = setInterval(() => { val = genObj.next(); If (val.done) { clearInterval(间隔); }其他{ console.log (val.value); } }, 1000); 函数* genFunc() { For (let item of arr) { 收益项; } }

所以如果你正在使用ES6,这是实现延迟循环的最优雅的方式(在我看来)。

其他回答

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

你也可以通过使用一个自调用函数,将迭代次数作为参数传递给它:

(函数myLoop(i) { setTimeout(函数(){ console.log('你好');//你的代码 if(——i) myLoop(i);//减少i,如果i > 0再次调用myLoop }, 3000) }) (10);//传递迭代次数作为参数

在ES6中,你可以这样做:

对于(设I = 0;I <= 10;我+ +){ setTimeout(函数(){ console.log(我); },我* 3000) }

在ES5中,你可以这样做:

For (var I = 0;I <= 10;我+ +){ (函数(i) { setTimeout(函数(){ console.log(我); },我* 3000) }) (); }

原因是,let允许您声明限制在块语句或使用它的表达式范围内的变量,而不像var关键字那样全局定义变量,或局部定义整个函数,而不考虑块范围。

你可以使用RxJS的间隔操作符。Interval每x秒发出一个整数,take指定它发出这些数字的次数。

Rx。可观测的 .interval (1000) (10), .subscribe((x) => console.log(x)) < script src = " https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.1.0/rx.lite.min.js " > < /脚本>

您可以创建一个承诺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)}); } })()