Bringing setTimeout to ECMAScript

Mark S. Miller erights at
Sat Mar 19 13:05:44 PDT 2011

On Sat, Mar 19, 2011 at 10:57 AM, David Bruant <david.bruant at>wrote:

>  Le 19/03/2011 17:58, Mark S. Miller a écrit :
> [...] The two things I'd fix in this lower layer abstraction:
>  * No clamping. Time runs as fast as the platform lets it run.
> * The return value is not an integer but a unique unforgeable object
> for canceling the event. No one without that object can cancel that event.
> This last point is something I was about to raise when starting to think
> about extending the Q API.
> setTimeout returns a number, so a malicious could loop through numbers and
> call clearTimeout on them. An unforgeable object sounds like the correct
> response to this issue. Have you considered wrapping setTimeout&friends in
> SES with this solution? It wouldn't break code which do not rely on the
> returned value being a number (but would break code which does, of course).

Caja does exactly this. So far we haven't found any code that this actually
breaks. All uses we've encountered[1] treat the return value of
setTimeout/setInterval as simply something they can remember and later pass
to clearTimeout/clearInterval.

[1] That I'm aware of. Caja users should speak up if they've hit a
counter-example. Or anyone else that has seen code in the wild that actually
counts on these values being numbers.

I actually haven't thought about this in the context of SES, and I must.
Thanks for raising this.

> I think there would be a need to wrapped the passed callback in order to
> achieve garbage collection.

I didn't understand that. Could you expand? Thanks.

> I agree on the rest you've said except one thing: I'm not really sure ES
> should standardized the 4ms clamping. It is a reality in web browsers and
> maybe fair for the WHATWG to standardize it as such for web backward
> compatibility, but maybe that other non-web browser ES-based implementations
> do not follow this 4ms restriction. Any idea if there is a 4ms clamping in
> node.js setTimeout? Or in other ES-based implementations?
> If there is none, the ECMAScript spec could just leave some room to
> implementation-dependent behaviors.

I like this approach. Does anyone know of any problems leaving the 4ms issue
as dependent on the hosting environment, and not to be standardized as part
of an ES setTimeout/setInterval standard?

> After giving it further thought, here are the ideas I've had on adding time
> to the Q API:
> Q.when(timedPromise, success); would be a nice syntax to call a 'success'
> function when the promise is resolved.

I don't understand. Given that timedPromise is the kind of thing that
delay() returns, just doing a Q.when() on a timePromise as above will
already do the right thing. That's why the delay() and race() abstractions
compose so nicely -- because race() does a Q.when on the promise returned by

I suspect I'm misunderstanding you. I'll wait for clarification on this
point before proceeding with the rest.

> To reject a timedDefered, something like:
> timedDeferred.resolve(Q.reject('')) could do it. But it requires providing
> the resolver to the timedDeferred creator. I do not know if it's a good idea
> to provide the resolver to user script since, in the way I see it, the
> resolver should exclusively be given to the engine which has the
> responsibility to manage time. I may be wrong. It however could be an
> occasion to trigger a promise resolution in advance.
> In Kris Kowal Q implementation (my (untouched) fork
>, 'reject' is
> provided as part of the promise if I understand well. Providing the rejecter
> but not the resolver could be a way to solve the second use case without
> providing the resolver to the user script.
> Do people have opinions on the resolver being provided or not to the user
> in case of a timed defered?
> Something that could be convenient in the timedPromise/Deferred construtor
> would be to be allowed to pass a Date object. If I want a promise to be
> resolved when my next birthday happens, I would prefer to write
> Q.timedDefer( Date(2012, 3, 8, 12) ) instead of computing milliseconds since
> 1/1/70. A decision would have to be made for dates in the past (actually,
> for negative number of milliseconds too)
> On the constructor itself, maybe an optional argument could be given to
> Q.defer. Maybe it would be better to have a Q.timedDefer function. These are
> just ideas. I have no strong opinion.
> David

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list