Bringing setTimeout to ECMAScript

Jorge jorge at jorgechamorro.com
Sun Mar 20 08:04:52 PDT 2011


On 20/03/2011, at 15:18, David Bruant wrote:
> Le 20/03/2011 14:33, Jorge Chamorro a écrit :
>>> A timer that expires is an event, and I would expect events to be serviced in the order they happen. As when I click twice, I'd expect the first click to be serviced before the second click.
>>> 
>>> So given 2 timers, expiring at t0 and t1 with t0 < t1, if Date.now() is >= t0 and >= t1, I would expect t0 to be serviced first, yes.
>>> 
> The difference is that the system can understand what is your expectation as a user when you've clicked twice. Both click are clearly sequenced. For timers, the non-determinism due to the computation time of computea and computeb prevents you from /expecting/ anything.

Why ? When you do a setTimeout( f, ms ) you know you are saying "fire this @ t >= Date.now() + ms". (Let's leave aside for now the problems wrt Date.now() / wall clock time).

> Once again, I agree with the policy, but there is no way to enforce it within the spec. 
> There is no way to write an ECMAScript test to be added to test262 to tell which implementation is valid and which is not. For anything tied to real time, it's impossible. The best test that could be written for Date.now() is to make sure that the returned value is bigger than the date when the test has been written. Or maybe, making sure that two sequential calls verify that the time goes forward. That's the best we can do.
> I do not really understand how you can "expect" things if you can't verify if your expectation is met or not.

I don't see why "you can't verify your expectation".

> In low-memory environment, if a program does an intensive use of timers, maybe that heuristics on the time the timer firing will take could be used to try to get rid of a maximum of timers as soon as possible to save up memory. I would consider this policy as valid due to environment constraints. 
>> And if t0 were === t1, I would also expect them to be serviced in the same order in which they were setup:
>> 
>> setTimeout( f1, 0 );
>> setTimeout( f2, 0 );
>> setTimeout( f3, 0 );
>> setTimeout( f4, 0 );
>> setTimeout( f5, 0 );
>> 
>> ->
>> f1()
>> f2()
>> f3()
>> f4()
>> f5()
>> 
> I think it is very dangerous to use talk about things like t0 === t1 and Date.now() >= t0 (concerned about the "or equal"). If ECMAScript has millisecond as granularity, most systems have microseconds if not nanoseconds. 1ms = 10⁶ns. That's a lot! It leaves a lot of room for interpretation. And even the setTimeout calls aren't instantaneous.
> 
> Consider (milliseconds in comment):
> // 0
> setTimeout( f1, 1 );
> setTimeout( f2, 0 ); // 1 (millisecond change in the middle of the call)
> // 2
> // -- decision to make on which timer to fire.
> Since the millisecond change happened during the second setTimeout, when is scheduled this second timeout?

A setTimeout( f, ms ) should be scheduled to fire at t = Date.now() + ms, so in the example above, both would be scheduled to fire at the same t, but, as f1 was setup before f2, f1 should be called before f2. You can achieve this easily with a stack per target time.

> (...)

-- 
Jorge.


More information about the es-discuss mailing list