Anna
Anna

Reputation: 121

What is happening to my setTimeout function?

I am trying to make a function(next) that takes a function and a wait time as its arguments. It will then have a counter that will be increased by the function calls.

var up = function() {
    var counter = 0;  
   return counter += 1;
};

var next = function(fn, wait) {
    var total = 0; //set total variable to 0
    var x = fn(); //call the function and set answer to a variable
    total+=x; //add the answer to the total

    var n = setTimeout(function(){fn();}, wait); 

//THIS BIT DOES NOT GIVE ME 1? Instead I get any number from 16 (depenging on how many times I call it! It increases as I keep calling the function....?!)

    total += n; 
    return total; 
};
next(up,1000);

I am totally confused as to why setTimeout is working like this?!

I have looked around for an answer for this and have not hit lucky- I am sorry if I have missed the question on here if it has been asked before! I did come across this question and tried putting the variable counter outside, however this did not seem to make any difference...

This question seems even closer to the area I am confused about however I am not any closer to comprehending my problem any help would be greatly appreciated as to why the return values that I am getting are so much higher than what I expect them to be..

Another approach that I tried was this:

var next = function(func, wait) {

    var storedAnswer = 0;
    var answer = function() {
        return storedAnswer;
    }
    var increase = func;
    setTimeout(increase, wait); 
    return answer();
};

next(up, 100);  // gives me 0...? the up function here is defined in the above code...

But this ended up with me not getting any movement in the answer...

Upvotes: 1

Views: 113

Answers (3)

Travis J
Travis J

Reputation: 82287

The value that setTimeout returns is an int. But it is also a global counter of timeouts. Which is to say that every timeout shares the same counter. So that you get 16 just means that somewhere, in some part of your page, 15 other timeouts had already executed.

This is perfectly normal to get back an integer of 16 or basically of not 1 in that scenario, and using that integer with a clearTimeout for example will still properly reference the timeout used.

Aside

In node.js (which doesn't seem like what you are using), the mechanism is the same, except that a timeoutObject is returned instead which may still be used to clear the timeout. It is also used for continuations and other server-side related timing mechanisms.

Upvotes: 1

Josiah Keller
Josiah Keller

Reputation: 3675

n is the return value of setTimeout, which is a numeric identifier that you can pass to clearTimeout in order to cancel the timeout.

Your basic problem here is that setTimeout simply registers a function to be called after the given delay, and then execution immediately continues to the next line. So this line:

total += n;

is not waiting until your timeout completes. It's happening immediately, and n is, like I said, not the value you want.

You need your next function to take a callback that it can call when the timeout has completed.

var next = function(fn, wait, callback) {
    var total = 0;
    var x = fn();
    total+=x;

    setTimeout(function() {
        var n = fn();
        total += n;
        callback(total);
    }, wait); 
};

You would call it like:

next(up, 100, function(total) {
    // This function runs after the operation is done; do something with the total.
});

Upvotes: 0

gpojd
gpojd

Reputation: 23065

setTimeout returns the timeout id, not the return value of the callback.

var timeoutID = window.setTimeout(code, [delay]);

Try this:

setTimeout(function(){total += fn();}, wait);

Upvotes: 1

Related Questions