[whatwg] Polling APIs in JavaScript vs Callbacks

Glenn Maynard glenn at zewt.org
Thu Feb 7 17:32:03 PST 2013

On Thu, Feb 7, 2013 at 6:24 PM, Gregg Tavares <gman at google.com> wrote:

>  Anyone have time to give me some advice, tips, pointers?
> In the next WebGL we have Query/Sync objects. In C/C++ land the user can
> insert some drawing commands that will happen asynchronously on the GPU.
> They can also insert a query. They can then poll that query (did this
> finish?).

Before I get into the technical discussion of polling vs. events, I'd like
to look at this briefly from a higher level.

A big problem with WebGL is that it tends to disregard the conventions of
the platform; it "does its own thing".  For example, it uses slews of
functions with different names, instead of collapsing logical overloads.
It also has another slew of functions--deleteBuffer, deleteFramebuffer,
deleteShader--which could easily have been a single "delete(WebGLObject)",
or much better a "delete()" function on WebGLObject.  This makes WebGL feel
more like a naive copy of OpenGL, designed by a C programmer, than a
well-thought-out binding.

This is just to say: callbacks are the pattern on on the platform, not
polling, and WebGL should follow that pattern, not go its own way and make
up its own conventions.  If people don't understand why the platform's
conventions are what they are, and think they should be something else,
please encourage them to come here and discuss it--not to try to make WebGL
its own isolated island.  That's damaging to WebGL and the platform as a

We'd like to expose that to JavaScript. I've been pushing to making it a
> callback in JavaScript rather than polling. Most graphics developers I talk
> to hate this idea.

Polling is expensive, especially if you don't already have a render loop to
poll from (eg. single-shot rendering, and load screens).

It's also latent.  If you're polling from requestAnimationFrame (for
example), you're probably checking every 16ms.  That means there may be up
to 16ms extra delay, if the task finished right after the last poll.  This
encourages people to set timers that run as fast as possible, in order to
lower latency, which makes it more and more expensive and runs up against
timer throttling.

But. that comes back to (a) above. Move devs I've talked to really don't
> want to use callbacks. They're all good devs and they know what they're
> doing and they don't want to deal with what they consider callback/closure
> hell. Especially when they need to acquire multiple things at once.

There's no "callback hell"; it's very easy to wait for many things to
finish with just a single callback.  Here's an example, which loads a bunch
of images with <img>, and calls a function when they're all done loading:


It's very simple: each time an image finishes loading, the callback checks
whether all resources have finished loading.  If there are still images in
the process of loading, it returns and waits for the next one to finish.
Otherwise, it's done.  There's just a single, trivial closure.

Images are not quite analogous though as there is no polling built in
> polling on an image to find out if it's finished.

Actually, there is.  Changing "img.onload = onload" to "setInterval(onload,
100)" (and adding a clearInterval in the appropriate place) in the above
sample turns it into a poll.

Glenn Maynard

More information about the whatwg mailing list