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


当前回答

我可能会使用setInterval,像这样:

var period = 1000; // ms
var endTime = 10000;  // ms
var counter = 0;
var sleepyAlert = setInterval(function(){
    alert('Hello');
    if(counter === endTime){
       clearInterval(sleepyAlert);
    }
    counter += period;
}, period);

其他回答

下面是我用来循环数组的函数:

function loopOnArrayWithDelay(theArray, delayAmount, i, theFunction, onComplete){

    if (i < theArray.length && typeof delayAmount == 'number'){

        console.log("i "+i);

        theFunction(theArray[i], i);

        setTimeout(function(){

            loopOnArrayWithDelay(theArray, delayAmount, (i+1), theFunction, onComplete)}, delayAmount);
    }else{

        onComplete(i);
    }
}

你可以这样使用它:

loopOnArrayWithDelay(YourArray, 1000, 0, function(e, i){
    //Do something with item
}, function(i){
    //Do something once loop has completed
}

如果使用ES6,你可以使用for循环来实现:

For(令I = 1;I < 10;我+ +){ setTimeout(函数定时器(){ console.log(“hello world”); }, I * 3000); }

它为每次迭代声明i,这意味着超时是+ 1000之前的超时。这样,传递给setTimeout的就是我们想要的。

在ES6中,你可以这样做:

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

在ES5中,你可以这样做:

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

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

对于常用的“忘记正常循环”和使用这个组合的“setInterval”包括“setTimeOut”:像这样(从我的实际任务)。

        function iAsk(lvl){
            var i=0;
            var intr =setInterval(function(){ // start the loop 
                i++; // increment it
                if(i>lvl){ // check if the end round reached.
                    clearInterval(intr);
                    return;
                }
                setTimeout(function(){
                    $(".imag").prop("src",pPng); // do first bla bla bla after 50 millisecond
                },50);
                setTimeout(function(){
                     // do another bla bla bla after 100 millisecond.
                    seq[i-1]=(Math.ceil(Math.random()*4)).toString();
                    $("#hh").after('<br>'+i + ' : rand= '+(Math.ceil(Math.random()*4)).toString()+' > '+seq[i-1]);
                    $("#d"+seq[i-1]).prop("src",pGif);
                    var d =document.getElementById('aud');
                    d.play();                   
                },100);
                setTimeout(function(){
                    // keep adding bla bla bla till you done :)
                    $("#d"+seq[i-1]).prop("src",pPng);
                },900);
            },1000); // loop waiting time must be >= 900 (biggest timeOut for inside actions)
        }

PS:理解(setTimeOut)的真实行为:它们都将在同一时间开始“三个bla bla bla将在同一时刻开始倒数”,因此设置不同的超时来安排执行。

PS 2:计时循环的例子,但对于一个反应循环,你可以使用事件,承诺async await ..

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);//传递迭代次数作为参数