Zach’s ugly mug (his face) Zach Leatherman

enterval, an automatic setInterval chainer.

December 23, 2007

Hello internet. Today we’ll be exploring the magical wonders of setInterval. Have you ever worked on a project that needed multiple timers going simultaneously? Have you ever wanted to bind all of those timer callbacks into just one timer without restructuring your code manually? Well, being the Curious George that I am, I wanted to know the performance benefits of the grouping callbacks and eliminating unnecessary timers. Here’s the code I used to do it:

Instead of:

window.setInterval(function(){ /* Payload! */ }, 100);
window.setInterval(function(){ /* Payload! */ }, 100);
window.setInterval(function(){ /* Payload! */ }, 100);
// results in three separate timers.

You can do:

enterval.set(function(){ /*Payload */ }, 100);
enterval.set(function(){ /*Payload */ }, 100); // combines with the first 100ms interval.
enterval.set(function(){ /*Payload */ }, 100); // combines with the first two 100ms intervals.
// results in one timer, containing all three callbacks.

Here’s the code:

var enterval = (function()
{
    var intervals   = {};

    function add(callback, interval)
    {
        var index = 0;
        if(intervals[interval]) {
            index = intervals[interval].length;
            intervals[interval].push(callback);
        } else {
            intervals[interval] = [callback];
            window.setTimeout(call, interval, interval);
        }
        return interval+':'+index;
    }

    function call(interval)
    {
        var d = intervals[interval];
        for(var j=0,k=d.length;j<k ;j++) {
            if(typeof d[j] == 'function' && d[j]() === false) return;
        }
        window.setTimeout(call, interval, interval);
    }

    return {
        set: function(callback, interval, data)
        {
            return add(callback, interval, data);
        },
        clear: function(id)
        {
            var s = id.split(':');
            delete intervals[s[0]][s[1]];
        }
    };
})();

Unfortunately, in the limited benchmarks that I performed, it didn’t seem to operate all that much differently from recursive setTimeout calls, even with (10ms, 100ms, or 1000ms) intervals and (50, 100, 1000) timers (with the payload doing nothing other than creating a date for benchmarking purposes. This code does get around the oddly performing setInterval inside of a loop bug. There may be some other benefit in ordering the interval callbacks after assignment, but I haven’t included that in the functionality above. Feel free if you wish.


< Newer
Quine using XHTML and JavaScript
Older >
Obscurity, Security, and Captcha

Zach Leatherman IndieWeb Avatar for https://zachleat.com/is a builder for the web at IndieWeb Avatar for https://cloudcannon.com/CloudCannon. He is the creator and maintainer of IndieWeb Avatar for https://www.11ty.devEleventy (11ty), an award-winning open source site generator. At one point he became entirely too fixated on web fonts. He has given 79 talks in nine different countries at events like Beyond Tellerrand, Smashing Conference, Jamstack Conf, CSSConf, and The White House. Formerly part of Netlify, Filament Group, NEJS CONF, and NebraskaJS. Learn more about Zach »

Shamelessly plug your related post

These are webmentions via the IndieWeb and webmention.io.

Sharing on social media?

This is what will show up when you share this post on Social Media:

How did you do this? I automated my Open Graph images. (Peer behind the curtain at the test page)