【问题标题】:Unexpected behavior in setTimeOut in for loopfor 循环中 setTimeOut 中的意外行为
【发布时间】:2019-02-14 20:04:17
【问题描述】:

我正在尝试以特定的时间间隔将数字记录到控制台。但是,发生的情况是它等待设置的时间间隔,然后正常记录所有内容。

我尝试了两种不同的方法来创建闭包。但是对于延迟的 console.log 什么也不做。

function timeOutLoop(x){
   for(var i = 0; i<=x; i++){
    (function(n){
      setTimeout(function(){console.log(n)},5000)
    })(i)

     setTimeout(function(num){
      return function(){
        console.log(num)
      }
    }(i),1000)
  }
}

timeOutLoop(33)

我的印象是,每个 setTimeout 都会使用闭包提供的上下文进入事件队列。什么给了?

【问题讨论】:

  • 您为每个计时器提供完全相同的等待时间。 (以及 2 个不同的等待时间,但仍然如此。)
  • 要明确:外部for 循环将基本上立即结束;设置每个计时器需要几微秒。然后,它们将全部等待 1 或 5 秒,并同时熄灭。这就像同时点燃了 33 个鞭炮的导火索。
  • 谢谢。我应该如何进行?你想要官方的答案还是我自己来回答?
  • 那么你想做什么?一种可能性是将您的计时器常数(1000 或 5000)乘以迭代值,为每个计时器提供自己的延迟。

标签: javascript


【解决方案1】:

setTimeouts 同时开始,所以如果你想一个接一个地开始超时,你可以创建一个递归函数:

function timeOutLoop(x, i=0){
   if(i<=x){
      console.log(i);
      i++;
      setTimeout(function(){timeOutLoop(x, i)},1000);
   }
}
timeOutLoop(33)

你可以设置任何你喜欢的超时值。

【讨论】:

    【解决方案2】:

    由于循环基本上是立即执行的,所以与第一个没有太大区别,因为时间是以毫秒为单位的,而对于第二个,它们都会在1秒后执行。

    结合使用这两种方法,可以实现:

     function timeOutLoop(x) {
      for(var i = 0; i <= x; i++) {
        setTimeout(function(num) {
          return function(){
              console.log(num);
          }
        }(i), i * 1000);
      }
    }
    
    timeOutLoop(33)

    【讨论】:

      【解决方案3】:

      function timeOutLoop(x){
          for(let i = 0; i<=x; i++){
              setTimeout(function(){console.log(i)},i * 1000);    
          }
      }
      timeOutLoop(33);

      这就是你要找的吗?从 var 更改为 let 以保持变量 i 在循环范围内的完整性。 More here about let vs var.

      还将i 乘以 1000 以每秒打印一次,直到达到 33。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-02
        • 2023-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-10
        • 2020-06-06
        • 1970-01-01
        相关资源
        最近更新 更多