setTimeout和带参数的递归函数

setTimeout and recursive function with parameters

本文关键字:递归函数 参数 setTimeout      更新时间:2023-09-26

我正试图做这样的事情:

我只想在选项卡加载了类时调用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);
    }
}

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

实际执行的是执行函数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()

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

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

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