4

This is with regard to how setTimeout executes its callbacks.

I have have the following

function f1 (argument) {
    console.log('f1 start');
    for(var i = 0; i < 100000; ++i)
        for(var j = 0; j < 10000; ++j);
    console.log('f1 complete');
}

function f2 (argument) {
    console.log('f2 start');
    for(var i = 0; i < 1000; ++i)
        for(var j = 0; j < 10000; ++j);
    console.log('f2 complete');
}

function f3 (argument) {
    console.log('f3 start');
    for(var i = 0; i < 10000; ++i)
        for(var j = 0; j < 10000; ++j);
    console.log('f3 complete');
}

setTimeout(f1,0);
setTimeout(f2,0);
setTimeout(f3,0);
console.log('In main2');

Output:

In main2

f1 start

f1 complete

f3 start

f3 complete

f2 start

f2 complete

John Resig explains in his article, setTimeout queues all the callbacks until the current block of code completes its execution. This StackOverflow answer explains even though it appears as if the events are fired immediately, they are actually queued.

In the above code you'd notice, f1() is the longest, followed by f3() and then f2().

My question is, why the observed order(f1 first, then f3 and finally f2)? If the events are queued, it should simply be in the same order as they were called (f1,f2,f3). How and why does the JavaScript engine pick the longest job first?

[EDIT] Note: The above code was run in Node.js

Community
  • 1
  • 1
  • check this out : https://github.com/caolan/async – trrrrrrm Sep 20 '13 at 07:47
  • I got the sequenced output in node as well `f1 f2 then f3` – exexzian Nov 02 '13 at 12:01
  • 1
    I don't see how it is possible for you to get that output. The functions must always be called in order (i.e. `f1`, then `f2`, then `f3`). There's no way for JavaScript to figure out the longest function without profiling it. Asynchronous functions are always queued. – Aadit M Shah Apr 11 '14 at 15:37

2 Answers2

1

I have tried your code in firebug console and I got the output in following order, which I think as expected.

In main2 f1 start f1 complete f2 start f2 complete f3 start f3 complete

I am using firefox 12.0 with fedora.

Vineesh
  • 467
  • 4
  • 11
0

Regardless of the "javascript engine" question (there is no such thing, there is a language specification and different implementations) because it depends (see this another answer), you may want to use promises if you want to ensure a specific sequence order.

Check the Q library at https://github.com/kriskowal/q

Or this RSVP library https://github.com/tildeio/rsvp.js

The Promises/a+ spec is here

Is available for node and for the browser

My own test on node v0.10.21 (same as firefox and chromium's console):

~/workspace/tmp$ node test.js 
In main2
f1 start
f1 complete
f2 start
f2 complete
f3 start
f3 complete
Community
  • 1
  • 1
nico
  • 624
  • 11
  • 22
  • 1
    Thanks for that SO question - makes me wonder about the source of John Resig's article. And FYI, there's a wiki page on [Javascript Engine](https://en.wikipedia.org/wiki/JavaScript_engine). So, it wouldn't entirely be wrong to say that there is such a thing would it? :) –  Dec 30 '13 at 17:24
  • 1
    There is a section "Implementations" in that wiki article that says what I say, but yes, it's not entirely wrong to say it :) – nico Dec 30 '13 at 18:29