Travis James
Travis James

Reputation: 1939

passing arguments into recursive functions

So I have a recursive function using setTimeout() and I cannot figure out how to continue to pass my argument into the recursive function that setTimeout() is calling. I tried using .bind(null, time) and passing the argument that way but it doesn't seem to work.

I also tried using the third option available for setTimeout that I thought was for passing in variables but that doesn't seem to work either. I will try to explain with my code example...

All I am using this function for is a way to set different timeout delays..

function delay(t) {
    return (500 - (t * pattern.length));
}

this is what is causing me the trouble

function next(time) {
    //random code ~turn on//

    setTimeout(function() {
        //random code ~turn off//

        if(score < 50) { 
        setTimeout(next.bind(null, time), delay(time));
        }
    }, delay(time));
}

And when I call the function

next(30)

The //random code ~turn on part of my code runs fine, but then it almost seems like the setTimeut function is running without any delay at all. Like the time variable (30) isn't being passed in. Also I am getting no error codes in the console.

Thanks for any help!

Upvotes: 1

Views: 1400

Answers (1)

Mark
Mark

Reputation: 92440

I'm not sure if you are trying to do something complicated or it you are complicating something simple. But with the code as it is, the biggest problem is that you are shadowing your time argument:

function next(time) {
    //random code ~turn on//

    setTimeout(function(time) {
        // time is now undefined, because nothing is passed in
        // to to setTimeout third param


        if(score < 50) { 
         // time here no longer refers to the `time` passed into
         // next, but rather the undefined value delcared as a parameter 
         // to the callback to setTimeout.
         setTimeout(next.bind(null, time), delay(time));
        }
    }.bind(null, time), delay(time));
}

The result is that your timeout get called with undefined delays. Removing that will let it work (if I understand what you are doing). You can also just pass a function into timeout that capture the time closure so you don't need bind:

// fake score and delay for demonstration purposes
function delay(t) {
    return t;
}

function next(time) {
    setTimeout(function() { // don't pass a paran here (or if you do, rename it)
        let score = Math.random()
        console.log("running", score)
        if(score < .80) { 
           setTimeout(next.bind(null, time), delay(time));
        }
    }, delay(time));
}
next(1000)

Upvotes: 2

Related Questions