【问题标题】:Why is setInterval making infinite loops为什么 setInterval 会造成无限循环
【发布时间】:2016-05-13 03:47:57
【问题描述】:

我正在尝试设置一个计时器,以便它显示用户的秒数和分钟数,我正在使用 setInterval 来获取秒数,如果有 60 秒,它将减少用户的 1 分钟。 问题是每次我尝试这样做时都会遇到无限循环。

类似

var userObj = {
    name: "",
    min: 0,
    sec:0
}

function timerCount() {
    while (userObj.sec !== 0) {
        console.log(userObj.min)
        if (userObj.sec == 0) {
            setInterval(function() {
                userObj.min--;
                userObj.sec = 59     
            }, 1000);
        }
        while(userObj.sec !== 0) {
            setInterval(function() {
                console.log(userObj.sec)
                userObj.sec--;  
            }, 1000);
        }
    }
}

【问题讨论】:

  • 你需要将setInterval()存储在一个变量中,并clearInterval(variable)来停止它,否则它会无限调用
  • 浏览器或 node.js 中的 Javascript 是一种事件驱动语言,并且是单线程的,因此您不能在 while() 循环中循环并期望执行任何其他计时器代码。在您完成 while() 循环之前,计时器回调永远不会执行。因此,您不能像这样循环等待计时器更新某些内容。计时器永远不会执行,所以你只会有一个无限循环。
  • 这里至少有几个问题。 1)您在 while 循环中调用 setInterval() 。 setInterval() 将回调设置为重复调用(在您的情况下每 1000 毫秒)。但是您在 while 循环中调用 setInterval(),因此您设置了多个并行执行的时间间隔。 2) setInterval() 中的回调函数与其余代码异步调用。因此,您无法在回调中修改 userObj.sec 并看到它们以您期望的方式影响您的 while 循环。

标签: javascript jquery time setinterval


【解决方案1】:
var userObj = {
    name: "",
    min: 0,
    sec:5
}

function timerCount() {

  if(userObj.min === 0 && userObj.sec === 0) {
    return;
  }

  if (userObj.sec === 0) {
    userObj.min--;
      userObj.sec = 59     
    }     
  userObj.sec--;  


  setTimeout(timerCount, 1000)
}

timerCount()

我们可以毫不费力地删除那些导致问题的 while 循环。我们还想检查分钟和秒是否等于 0,以便我们知道何时结束计时器。

【讨论】:

    【解决方案2】:

    你把你的 setInterval 放在一个循环中(和其他东西)。

    无需以分钟和秒为单位分隔时间,只需使用秒数并做一些数学运算。

    这是一个有效的代码:

    var userObj = {
        name: "Joe",
        sec: 3605
    }
    
    function timerCount()
    {
        var interval = setInterval(function()
        {
            console.log(getTimeLeft(userObj.sec));
            userObj.sec--;
            if(userObj.sec == 0)
            {
                clearInterval(interval);
                console.log('NO MORE TIME');
            }
        }, 1000);
    }
    
    function getTimeLeft(sec)
    {
        var seconds = Math.floor( sec % 60 );
        var minutes = Math.floor( (sec / 60) % 60 );
        var hours = Math.floor( (sec / 60 / 60) );
    
        return {
            'hours' : hours,
            'minutes': minutes,
            'seconds': seconds
        }
    }
    
    timerCount();
    

    【讨论】:

      【解决方案3】:

      这是您可以想到的另一种方法:

      function timer(min, sec){   
          if (min === 0 && sec === 0) return;
      
          setTimeout(function(){
             console.log(min, sec);
      
             if (min > 0 && sec === 0) timer(min-1, 59);
             if (sec > 0) timer(min, sec-1);  
          }, 1000);
       }
      

      您可以调用此计时器:

      timer(userObj.min, 0)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-09-21
        • 2010-10-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-19
        • 2011-08-18
        相关资源
        最近更新 更多