setTimeout和带参数的递归函数

时间:2014-09-17 11:57:46

标签: javascript recursion settimeout

我正在尝试做类似的事情:

我想仅在选项卡加载了类时调用doSomething()函数(可能需要3或5秒)。

function addInfosSinistre(msg){
     addInfosSinistreRecursive(msg, 0);
}

function addInfosSinistreRecursive(msg, nbCalls) {
    if ($("#tab").hasClass('loaded')) {
        doSomething();
    }else if (nbCalls < 10) {
        setTimeout(addInfosSinistreRecursive(msg, nbCalls+1),500);
    }
}

这不起作用,似乎计时器不起作用。这里有什么问题吗?

2 个答案:

答案 0 :(得分:1)

您实际执行的操作是执行函数addInfosSinistreRecursive并将返回值传递给setTimeout()。你真正想做的是传递函数参考。

这样做的一种方法是为变量创建一个闭包:

function addInfosSinistreRecursive(msg, nbCalls) {

  function timeoutHandler(){
    if ($("#tab").hasClass('loaded') ) {
        doSomething();
    }else if (nbCalls < 10) {
        nbCalls += 1;
        setTimeout( timeoutHandler, 500 );
    }
  }

  // first execution
  timeoutHandler();

}

函数timeoutHandler()可以将参数引用到addInfosSinistreRecursive(),并且没有自己的参数。因此,您可以将引用传递给setTimeout()

答案 1 :(得分:1)

是的,这里肯定有问题。您立即调用该函数并将undefined传递给setTimeout(),而不是给它一个函数来调用。这可以做你想做的事情:

function addInfosSinistreRecursive(msg, nbCalls) {
    if ($("#tab").hasClass('loaded')) {
        doSomething();
    }else if (nbCalls < 10) {
        setTimeout(addInfosSinistreRecursive.bind(this, msg, nbCalls + 1), 500);
    }
}

但问题是你为什么要这样做?这似乎是一种令人费解的方式来做任何你想要完成的事情。您可能应该在更改选项卡时使用某个事件,而不是递归循环并等待选项卡更改。

相关问题