为什么我的javascript时钟会在一分钟后崩溃?

时间:2016-06-11 19:30:16

标签: javascript jquery

我已经对jshint进行了双重检查和测试,以了解语法错误等。我还将我的代码与创建相同时钟的其他人进行了比较,但没有看到任何会导致我的时钟崩溃的差异。我不明白是什么导致了这个问题。



$(document).ready(function(){

  function displayTime() {
    var currentTime = new Date();
    var hours = currentTime.getHours();
    var minutes = currentTime.getMinutes();
    var seconds = currentTime.getSeconds();
    var miridiem = "AM";

    var clockDiv = document.getElementById('clock');

    if(seconds < 10) {
      seconds = "0" + seconds
    }

    if(minutes < 10) {
      minutes = "0" + minutes
    }

    if (hours > 12) {
      hours = hours - 12
      miridiem = "PM"
    }

    if (hours === 0) {
      hours = 12
    }

    clockDiv.textContent = hours + ":" + minutes + ":" + seconds + " " + miridiem;

    setInterval(displayTime, 1000);
  }

  displayTime();
});
&#13;
<body>
 
  <div id="clock"></div>

  <script src="https://code.jquery.com/jquery-3.0.0.min.js" integrity="sha256-JmvOoLtYsmqlsWxa7mDSLMwa6dZ9rrIdtrrVYRnDRH0=" crossorigin="anonymous"></script>
</body>
&#13;
&#13;
&#13; 警告:片段会占用你的记忆。不要忘记阻止它。

https://jsfiddle.net/9cp9m43h/

3 个答案:

答案 0 :(得分:2)

您只是误解了setIntervalsetTimeout的使用情况。

正如一些评论者提到的那样,您可以将当前的实现更改为使用setTimeout,它可以很好地运行。

但是,在我看来,最好的解决方案是改变代码的工作方式,以便setInterval正常工作:

$(document).ready(function(){

  function displayTime() {
    var currentTime = new Date();
    var hours = currentTime.getHours();
    var minutes = currentTime.getMinutes();
    var seconds = currentTime.getSeconds();
    var miridiem = "AM";

    var clockDiv = document.getElementById('clock');

    if(seconds < 10) {
      seconds = "0" + seconds
    }

    if(minutes < 10) {
      minutes = "0" + minutes
    }

    if (hours > 12) {
      hours = hours - 12
      miridiem = "PM"
    }

    if (hours === 0) {
      hours = 12
    }

    clockDiv.textContent = hours + ":" + minutes + ":" + seconds + " " + miridiem;

  }

  displayTime();
  setInterval(displayTime, 1000);
});

我觉得这样更好,因为:

  1. 这是setInterval的设计目的:在特定时间间隔内反复执行相同的操作。
  2. 手动调用setTimeout以重置计时器会让您开启一些时钟偏差;如果displayTime在设置超时之前需要一毫秒才能运行,那么在1000秒之后你可能会大约1秒钟。
  3. 一个名为displayTime()的函数听起来就像它所做的一样是显示时间 - 没有什么可暗示它也会产生长期的副作用。如果计时器设置在该方法之外,则关注点分离会更好。
  4. displayTime()的效果在不产生异步副作用时更容易独立测试。

答案 1 :(得分:1)

我认为您的setInterval()位置错误。您将它放在函数内,该函数每分钟注册60​​个间隔监视器,因此内存崩溃。如果要在调用函数后触发下一个超时,可以使用setTimeout()函数中的displayTime()来执行此操作。但是如果你执行setInterval(),则希望在调用初始displayTime()函数的同一级别调用它。

看我的小提琴:https://jsfiddle.net/9cp9m43h/3/

答案 2 :(得分:0)

每次调用displayTime()时,它都会启动一个每秒调用displayTime()的新间隔。

因此,每秒钟调用该函数的次数是之前的两倍。 60秒后,这是Math.pow(2, 60) //=> 1152921504606847000次。

  

嗯,我很难搞清楚它是如何在displayTime()函数中使用setInterval()崩溃的,但在函数外部完全正常工作。

因为在这种情况下displayTime()没有调用自己甚至不是setInterval的往返。所以它保持单个Interval,因此每秒都会调用一次函数。