JavaScript: Repeat a function X times at I intervals I've written a general purpose repeat function which allows you to repeat a callback function X times separated by I intervals with the option to start immediately or after the interval. It can also default to just looping infinitely, which is what setInterval does. Is there a better approach, or any improvements people can provide? Make sure to comment out all but one of the examples :)

function repeatXI(callback, interval, repeat, immediate) {
    repeat = typeof repeat == 'undefined' ? -1 : repeat;
    interval = interval &lt;= 0 ? 1000 : interval;
    immediate = typeof immediate == 'undefined' ? false : immediate;
    var offset = immediate ? 0 : 1;
    var id = null;
    if (repeat &gt; 0) {
        for (var i = 0; i &lt; repeat; i++) {
            id = setTimeout(callback, interval * (i + offset));
        }
    } else {
        id = setInterval(callback, interval);
    }
    return id;
}

// Example
var someFunc = function () {console.log(1);}

// Repeats forever, 1 second apart
repeatXI(someFunc, 1000);
// Repeats 10 times, 1 second apart, beginning after 1 second
repeatXI(someFunc, 1000, 10);
// Same as above, but beginning now
repeatXI(someFunc, 1000, 10, true);
I don't see anything problematic with your code, but just for fun, here are some alternative approaches to various parts of the code. It's 100% DRY, and functionally identical to the original.

function repeatXI(callback, interval, repeats, immediate) {
  var timer, trigger;
  trigger = function () {
    callback();
    --repeats || clearInterval(timer);
  };

  interval = interval &lt;= 0 ? 1000 : interval; // default: 1000ms
  repeats  = parseInt(repeats, 10) || 0;      // default: repeat forever
  timer    = setInterval(trigger, interval);

  if( !!immediate ) { // Coerce boolean
    trigger();
  }
}


And here's a jsfiddle demo

If you want, you can return timer from the function (as I do in the demo), so you can clear it (i.e. cancel the repeater) elsewhere in your code.

Regardless of the implementation-specifics it's worth noting that timers are unreliable at the best of times (since JS is single-threaded). Depending on your needs it may not be a good idea to set n timeouts at n * interval as you do for finite repeats. If a few of the timeouts get blocked long enough, they'll all queue up, and fire at once, once the thread clears. With setInterval though, you're guaranteed that there'll be at least interval time between the callbacks.

So it depends on your needs how you want to implement it.