1

I was writing a server side job that was trying to throttle an operation by doing the following:

var throttle = 1000 / 20;
for (var i = 0; i < 80000; i++) {
    setTimeout(operation, Math.floor(throttle * i));
}

I recognize that sleep works better here, but node.js required a library so I tried to tough it out. However, this program would work for over a thousand of these things, and then... nothing. No error message, just nothing happening. I suspect that JS ran out of timeout slots.

I have since migrated to sleep, which appears to be working, but I am curious as hell as to how JS is dealing with the timeouts. Does anyone have any additional insight?

Thanks!

For what it's worth, I assume that the answer is in this file https://github.com/joyent/node/blob/master/src/timer_wrap.cc assuming it's not in V8 itself.

SapphireSun
  • 9,170
  • 11
  • 46
  • 59
  • It's definitely not V8 as `setTimeout` isn't a JavaScript language feature. – WiredPrairie Oct 23 '13 at 12:36
  • I'm not sure why your test hung ... it's still ticking :) away on my machine. I'd guess it's operating system dependent. This was my tiny change to your code so it was doing something visibly: `var throttle = 1000 / 20; for (var i = 0; i < 80000; i++) { (function(i) { setTimeout((function(){ console.log(i + " ticked! " + new Date().toLocaleTimeString()); }), Math.floor(throttle * i)); })(i); }` – WiredPrairie Oct 23 '13 at 12:41
  • What is `operation`? Your code works fine for me. – Aaron Dufour Oct 23 '13 at 17:13
  • Operation was just printing console.log for me. – SapphireSun Oct 23 '13 at 21:23

1 Answers1

1

Why don't you use setInterval(function, interval) instead?

var throttle = 1000 / 20;
var i = 0;
var interval = setInterval(function() { 
        operation();
        if(i++ == 80000) {
            // we're done
            clearInterval(interval); 
        }
    }, Math.floor(throttle * i));

(correcting, of course, for any off-by-one I've introduced)

Phil
  • 2,238
  • 2
  • 23
  • 34