G.Thompson
G.Thompson

Reputation: 827

Time based javascript functions with setInterval

I'm using node.js but this question is strictly javascript related. I'm interfacing with an i2c board to fade lights and I'd like to fade them at a specific rate, say 1 second. Now with setInterval, in theory it should work like... if I wanted to fade them 100 steps in 1 second I could just do something like...

var fader = setInterval(function(){
//will fade light 100 steps in 1 second
    doFade(something,something);
},10)

But depending on the code inside of the Interval loop, it may take longer than 1 second (I tested and for my application was about 2.5 seconds). I'm sure the fact that function doFade is taking a set amount of time to happen is causing this issue but I'm just curious if there is any real way to make this actually all happen within 1 second.

Upvotes: 1

Views: 402

Answers (1)

Elias Van Ootegem
Elias Van Ootegem

Reputation: 76408

The closest you'll ever get, AFAIK, relying entirely on JS would be to do something like this:

var fader = (function(now)
{
    var timeLeft, end = now + 1000,//aim for 1000 ms
        stepsRemaining = 100,
        callBack = function()
        {//define here, avoid redefining function objects
            doSomething(foo, bar);
            setter();
        },
        setter = function()
        {//recompute interval, set anew
            if (stepsRemaining <= 0)
            {//avoid infinite timeouts
                return;
            }
            timeLeft = (end - (+(new Date)));
            timeLeft= timeLeft > 0 ? timeLeft : 0;//ensure positive timeleft, if not, 0 intervals ==> ASAP
            fader = setInterval(
                callback,
                Math.floor(
                    timeLeft/stepsRemaining--
                )
            );
        };
    setter();
    return fader;
}(+(new Date)));//get ms now

This code, though untested creates all function objects beforehand. Then, using setter, everytime the interval finishes, as long as you haven't set 100 intervals, the new interval will be computed. After the work is done, by the callBack function, setter is called again. Here, the number of remaining steps is checked, then the timeLeft is computed again and based on the remaining steps, which are decremented by 1 on each call to setter.
To avoid setting the intervals too long, or using float-numbers, I'm calling Math.floor, and to avoid setting negative timeout values, I'm checking the value of timeLeft, too, obviously

Upvotes: 2

Related Questions