Javascript Asynchronous Problems

I've been doing some time-sensitive Javascript based animation recently and noticed a funny bug which is essentially related to throttling asychronicity in the browser. Essentially what I was doing was:

setTimeout(func, 0);

In my particular use-case I wanted to some logic to execute behind the scenes, away from the animation - otheriwse I could have just lumped it all in requestAnimationFrame. Using the setTimeout method introduced a very minor bug whereby if the user went very fast in the animation then the state/logic would be out of date by only fractions of a second - but surely it should be immediate right?

0ms not allowed

The HTML5 spec limits the minimum period of time specified for setInterval and setTimeout to be 4ms, before HTML5 this was 10ms - so essentially - if I want to kick off an asynchronous operation I am forced to wait for 4ms in modern browsers.

The case for setImmediate

Microsoft have done what I consider to be the right thing by introducing a new method named setImmediate, this essentially does what setTimeout(func, 0) looks like it should do, but it's being met with some heavy resistence by Mozilla and WebKit - and therefore is not cross-browser compatible. In fact Microsoft have taken advantage of this discrepency to fudge a few browser performance comparisons, but fudging performance comparisons is something that most browser vendors have been caught doing.

The case for Web Workers

I am both a fan of Web Workers and a hater of Web Workers. I'm a fan because it gives us a threading mechanism in Javascript that we can properly control, and I am also not a fan because Web Workers are fairly restricted, not completely cross-browser (yet) and complicate code. For my use case Web Workers would not work so I'm not going to dive into the complexities of it here but you can read about Web Workers from here and here.

The real cross-browser fix

The real fix involves (for some browsers) wrapping and messing with window.postMessage, this is actually (on some platforms) significantly faster than setTimeout(func, 0) might be and acheives the desired effect. For other browsers AJAX can be used (by using the onreadystate event) to execute code asynchronously, and for even older browsers.

I can't help but ask myself why browser vendors wouldn't want to at least wrap this approach in a method called setImmediate. In the meantime there's a nice JS library to do this for you.