Bringing setTimeout to ECMAScript

Kyle Simpson getify at gmail.com
Fri Mar 18 20:53:37 PDT 2011


>> Speaking as someone who has written and currently maintains a 
>> *synchronous* server-side JavaScript environment (based on V8), I attest 
>> to the statement that I would *not* like it if V8 had `setTimeout()` 
>> (...etc) in it, because unless V8 were going to take care of that 
>> completely black-box for me, then I'd have to either disable such 
>> interfaces, or figure out some more complicated functionality in my 
>> environment to handle the "concurrency".
>
> First, as a matter of principle, if it's in ES6 then V8 will implement. So 
> I'm told by people I trust.
>
>Second, what about your embedding is hostile to setTimeout, which is more 
>accurately weakly-isochronous than "asynchronous"?
>
>> I prefer they stay out of the engine, unless the engine is going to 
>> completely take care of it. The most important part of the engine "taking 
>> care of it" would be blocking the end of the program to wait for any 
>> outstanding event loop "turns" that had not yet fired, etc. Seems like 
>> that could get really messy.
>
> Read one way (the worst-case interpretation), this shows great confusion 
> about "threads suck", i.e., setTimeout requires no multi-threading. In no 
> scenario would there ever be multi-threaded blocking with races over 
> shared-mutalble state. What gave you this idea?
>
> Read another way, if you mean pseudo-threads implemented with setTimeout 
> never preempt one another but must all end before some larger notion of 
> "the program" ends, then what is the problem, exactly?


I understand that JavaScript doesn't have threads. I also understand that 
JavaScript doesn't have true concurrency. I furtermore understand that when 
I call `setTimeout(fn,1000)`, it queues up `fn` to run after at least 
1000ms, or later, at the next earliest "break" where there's a free "turn" 
for it to run.

What I was saying is, if I run this program through V8 right now (with its 
theoretical future support of setTimeout() included), then what will happen:

function fn() {
   print("hello");
}
for (var i=0; i<10; i++) {
   setTimeout(fn,i*1000);
}

That for-loop will finish very quickly (probably <1 ms). Would V8 (or any 
other JS engine) "finish" in the sense that the calling embedding code 
thinks this program is completely finished, and it returns back control to 
the C/C++ embedding layer when:

a) right after the for-loop finishes; OR
b) after only the first call to `fn`, since it's timeout was effectively 0, 
and so would have been immediately after the main program finished; OR
c) after all of the queued up calls to `fn` have finished, about 9 seconds 
later?

I have a C/C++ program that embeds the V8 API, and it loads up a bit of 
JavaScript from a file, and it tells V8 to execute that bit of code, then it 
loads up another file, and tells it to run that code, etc. What's 
problematic in my mind is if my hosting environment would be signaled that 
the first "program" finished, if there were still `fn`s that were queued up 
to be called. I would need the V8 execution API from my C/C++ code to be 
"blocked" and to wait for all of the "turns" of that code to be exhausted, 
and all the "isochronous" queued `fn` calls to finish, before letting me go 
on to run my next program.

In other words, to put it simply, if program A can call setTimeout(), and I 
want to run program A and then program B, I have to be able to make sure 
that I don't try to run program B until everything is fully finished in A. 
As V8 stands now, there's no way to do anything non-synchronous, so when A 
finishes, I know it's totally finished. I'm concerned that there'd be some 
new way with setTimeout()'s that this wouldn't be true.

--Kyle





More information about the es-discuss mailing list