setInterval

时间:2018-01-14 11:43:35

标签: javascript

很抱歉这样的基本qn。这是我做一个计时器的简单JS代码。我希望定期打印倒计时号码。我测试了其余的代码,它似乎工作,但是当我添加setInterval命令时,它让我很奇怪。我不知道为什么。因此,我寻求解释以及如何纠正它。 此外,当它工作时,新重新加载的号码应该替换旧号码。例如,当出现4时,它只是在倒计时期间替换5。

代码:

var x = prompt("Time till take off");



function printTimer (){
  document.write(x)
}

while (x > 0) {

  setInterval(printTimer,1000)
  x = x -1;
}

if (x=1){
  document.write("Rocket taken off")}

谢谢!

2 个答案:

答案 0 :(得分:1)

我认为以下代码片段可以满足您的需求。有关上下文的代码注释中有进一步的解释:



var output = document.getElementById('count-down');

/**
 * Initiates a countdown from given time in seconds
 * @param {number} count
 */
function countDown(count) {

    // Create the interval and save it in a variable 'interval'.
    // We need it later when the countdown reaches 0
    var interval = setInterval(function writeCount() {

        // If time till takeoff is greater than 0, we print the current
        // count and then decrement the count, so that next time count
        // will be ( count - 1 )
        if (count > 0) {
            output.innerText = count;
            count--;
            // OR: count -= 1';
            // OR: count = count - 1';
            // are all equivalent
        }
        // Otherwise we write a final value, and clear the timeout
        // so that we only get this final value once. If not cleared
        // the next second count will be -1, and this else block would
        // be re-executed.
        else {
            output.innerText = "Rocket taken off";
            clearTimeout(interval);
        }
    }, 1000);
}

countDown(prompt("Time till take off"));

<div id="count-down"></div>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

我认为@ jeffrey-westerkamp的解决方案很优雅,是实现结果的方法。但是,如果你很好奇为什么你当前的代码不起作用,那就是发生了什么。

有三大问题。

  1. 您使用setInterval代替setTimeout
  2. setInterval将以指定的时间间隔重复调用函数,直到它被取消。

    这意味着如果你的其余代码工作,它将输出“10,10,10,10,10,10,10 ......”“9,9,9,9,9,9, 9 ..“等等,直到你取消每个号码的间隔。

    setTimeout将来在指定的时间内调用指定的函数

    1. 您需要将变量x绑定到对每个setTimeout的调用。
    2. 现在,每次调用printTimer时,它都会查看x的值。但事情就是这样:对于每次调用,x的值将为0

      为什么呢? while循环将所有调用排队到setTimeout(或者在您的情况下setInterval。在将来的指定时间,printTimer被调用。当它执行时,它会查找变量x。当第一个printTimer调用运行时,x很久以来一直从while循环设置为零。

      1. 您需要根据倒计时序列中的位置确定调用setTimeout的延迟时间。
      2. for循环使这更加直观。像这样:

        function printTimer(count) {
          if (count===1){ console.log("Rocket taken off"); }
          else { console.log(count); }
        }
        
        for (var i=0;i<x;i++) {
          (function(count){
            setTimeout(printTimer.bind(null,x-count),1000*count);
          })(i);
        }
        

        for循环中的奇怪语法称为IIFE,或者是一个立即调用的函数表达式。在没有IIFE的情况下编写for循环的另一种方法是使用let而不是var:

        for (let i=0;i<x;i++) { //also works
          setTimeout(printTimer.bind(null,x-i),1000*i);
        }
        

        如果这令人困惑,请查看You Don't Know JS: Loops+Closure

        的此部分