以递归方式调用setTimeout函数并传递匿名函数

时间:2014-05-02 02:40:59

标签: javascript

我对这种语法之间的区别感到困惑:

var timerId;
 function clockStart(){
    // debugger;
    if(timerId){
      return;
    }
    update();
    // THIS LINE BELOW *********************************************
    var timerId = setTimeout(function(){clockStart()}, 1000);
  }
    function clockStop(){
      timerId = null;
    }
    function update(){
      var date = new Date();
      var hours = date.getHours();
      var minutes = date.getMinutes();
      var seconds = date.getSeconds();
      if(hours < 10) {
        hours = '0'+hours;
      }
      document.getElementById('hour').innerHTML = hours;
      if(minutes < 10){
        minutes = 0+minutes;
      }
      document.getElementById('min').innerHTML = minutes;
      if(seconds < 10){
          seconds = '0' + seconds;
      }
      document.getElementById('sec').innerHTML = seconds;
    }

我提供了两个被调用的函数,但是这个函数的主要部分我不明白为什么我需要传递一个匿名函数来调用我的clockStart()函数。

当我使用这种语法时,我的功能正常工作:

    var timerId = setTimeout(function(){clockStart()}, 1000);

但是当我使用它时它不起作用:

    var timerId = setTimeout(clockStart(), 1000);

我已经在这两个功能上工作了一段时间,我老老实实地偶然发现了这一点。除了调用我的clockStart函数之外,我真的不知道匿名函数在做什么。但在我看来,我的clockStart()函数应该每秒调用一次(1000ms),因为它调用自身,那么为什么需要一个匿名函数来调用它呢?不应该自己调用吗?

如果你想看到这个数字时钟的话。完整代码请查看我的代码集link

1 个答案:

答案 0 :(得分:4)

这一行:

var timerId = setTimeout(clockStart(), 1000);

立即调用clockStart()并将该函数的返回结果传递给setTimeout()。由于该函数不返回任何内容,因此您实际上是这样做的:

clockStart();
var timerId = setTimeout(undefined, 1000);

显然不能做你想做的事。


您可以改用:

var timerId = setTimeout(clockStart, 1000);

在这种情况下,您希望将函数引用传递给setTimeout(),这意味着您不包括parens。当你包括parens时,这意味着现在执行它。当您只传递函数的名称时,这只是对函数的引用(将其视为句柄),setTimeout()可以在以后调用它。这就是你想要的。

执行此操作时:

var timerId = setTimeout(function(){clockStart()}, 1000)

你只是定义了一个匿名函数,并将对该匿名函数的引用传递给setTimeout(),这可以正常工作,但在这种情况下不是必需的,因为你可以只传递clockStart名称在我上面的第三个代码示例中。


由于您询问某个函数以后如何调用某些内容,我将向您展示一个简单的示例。这是一个采用起始值,结束值,增量和回调函数的函数。这将调用回调并将其递增的值传递给它,直到该值超过结束值。

// define an increment function that will call a callback
// multiple times based on the start, end and increment arguments
function eachIncrement(start, end, increment, callback) {
    // the function argument named callback contains
    // a function reference
    var val = start;
    while (val <= end) {
        // execute the function reference and 
        // pass it the current val
        callback(val);
        val += increment;
    }
}

// define a function that we want to be called later
function processValues(num) {
    // this will get called multiple times with 
    // values 1, 4, 7, 10
}

// set up the increment parameters and pass a function reference
eachIncrement(1, 10, 3, processValues);