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


当前回答

一个无功能的解决方案

我有点晚了,但有一个不使用任何函数的解决方案:

alert('hi');

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

其他回答

你可以使用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()函数是非阻塞的,将立即返回。因此,您的循环将非常快速地迭代,它将快速连续地启动一个接一个的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);//传递迭代次数作为参数

据我所知,setTimeout函数是异步调用的。你能做的是将整个循环包装在一个异步函数中,并等待一个包含setTimeout的Promise,如下所示:

var looper = async function () {
  for (var start = 1; start < 10; start++) {
    await new Promise(function (resolve, reject) {
      setTimeout(function () {
        console.log("iteration: " + start.toString());
        resolve(true);
      }, 1000);
    });
  }
  return true;
}

然后像这样调用运行它:

looper().then(function(){
  console.log("DONE!")
});

请花些时间好好理解异步编程。

我可能会使用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);

我认为你需要这样的东西:

var TimedQueue = function(defaultDelay){
    this.queue = [];
    this.index = 0;
    this.defaultDelay = defaultDelay || 3000;
};

TimedQueue.prototype = {
    add: function(fn, delay){
        this.queue.push({
            fn: fn,
            delay: delay
        });
    },
    run: function(index){
        (index || index === 0) && (this.index = index);
        this.next();
    },
    next: function(){
        var self = this
        , i = this.index++
        , at = this.queue[i]
        , next = this.queue[this.index]
        if(!at) return;
        at.fn();
        next && setTimeout(function(){
            self.next();
        }, next.delay||this.defaultDelay);
    },
    reset: function(){
        this.index = 0;
    }
}

测试代码:

var now = +new Date();

var x = new TimedQueue(2000);

x.add(function(){
    console.log('hey');
    console.log(+new Date() - now);
});
x.add(function(){
    console.log('ho');
    console.log(+new Date() - now);
}, 3000);
x.add(function(){
    console.log('bye');
    console.log(+new Date() - now);
});

x.run();

注意:使用警报暂停javascript执行,直到你关闭警报。 它的代码可能比您要求的要多,但这是一个健壮的可重用解决方案。