Bringing setTimeout to ECMAScript
Mark S. Miller
erights at google.com
Sat Mar 19 13:05:44 PDT 2011
On Sat, Mar 19, 2011 at 10:57 AM, David Bruant <david.bruant at labri.fr>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 treat the return value of
setTimeout/setInterval as simply something they can remember and later pass
 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
> https://github.com/DavidBruant/q/blob/master/lib/q.js#L135), '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.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the es-discuss