1

If we run the setTimeout before the for loop (which takes like 5-8 seconds) and run this in chrome dev console the order of execution should be

  1. First setTimeout
  2. Second for loop
  3. Finally console.log

    setTimeout(function(){
        console.log('setTimeout executes');
    },1000);
    for(var i=0;i<10000;i++){
        console.log('inside for loop');
    }
    console.log('after For Loop');
    

But it doesn't and the order becomes:

  1. First for loop
  2. Second console.log
  3. and finally setTimeout

Why is this happening?

6
  • 1
    Second order is correct Commented Oct 16, 2018 at 7:41
  • 1
    Why do you think the setTimeout executes message should appear first? Commented Oct 16, 2018 at 7:41
  • 1
    😃 welcome to the world of asynchronous, single-threaded javascript Commented Oct 16, 2018 at 7:42
  • 3
    I find videos like this explain the event loop with animations etc far better than words can - I would add the link to this video in an answer, but then the answer would be low quality, and I couldn't do justice to what the video explains in mere words :p Commented Oct 16, 2018 at 7:43
  • when compiler compiles your code it put settimeout in brower stack to run after given time and it keep going through the code further. that is the reason, once it encounters the settimeout, it goes to browser and then it executes for loop and than console. As soon as settimeout is completes then inside code executes. Commented Oct 16, 2018 at 7:45

6 Answers 6

6

JS is sync. So all sync code is done first, and all async go in separate thread and they may finish earlier but they have to wait until all sync code is done.

setTimeout(function(){
    console.log('setTimeout executes');
},1000); // this function go async in separate thread
for(var i=0;i<10000;i++){ 
    console.log('inside for loop'); // sync
}
console.log('after For Loop'); // sync
// after all sync code async result will be called
// console.log('setTimeout executes'); will happen here

If you want full picture of how JS engines works read this. It is very basic and helps a lot.

Sign up to request clarification or add additional context in comments.

2 Comments

Not a bad answer, but V8 is not the only JS engine, and code passed to setTimeout is not (generally) run on a separate thread, but on the single execution thread when all synchronous code has completed and (approximately) the delay time has passed.
Yes, I've tried to provide the main idea (because question was from beginner). Probably thread is not best word, but haven't better in mind right now.
1

If you want to know the why, setTimeout is async. Javascript only guarantees that this callback won't be called BEFORE the time you specified, but doesn't guarantee it will happen exactly after. It places the call in the event queue (I think) and if something else is in there, this callback would have to wait.

You can learn a lot more in "You don't know JS" books which you can find here, read the async parts.

Comments

0

Because whatever the time passed into setTimeout, even if 0ms, it always takes some time before it executes, and so any other sufficiently small piece of code will run before the setTimeout call.

Comments

0

setTimeout(function(){...}, 0) simply queues the code to run once the current call stack is finished executing. This can be useful for some things.

So yes, it's asynchronous in that it breaks the synchronous flow, but it's not actually going to execute concurrently/on a separate thread. If your goal is background processing, have a look at webworkers. There's also a way to use iframes for background processing.

Comments

0

you try to exchange the position of

console.log('setTimeout executes');

and

for(var i=0;i<10000;i++){
    console.log('inside for loop');
}

1 Comment

and you can google the difference of setInterval and setTimeout
0

setTimeout runs the code you mentioned as an anonymous function after the timer expires. In your case it executes:

function(){
    console.log('setTimeout executes');
}

This does not halt the normal flow of the javascript.

To get the flow you want, you need to do it like this:

setTimeout(function(){
    for(var i=0;i<10000;i++){
        console.log('inside for loop');
    }
    console.log('after For Loop');
},1000);

To understand this better, you could use this visualization tool: http://latentflip.com/loupe

5 Comments

setTimeout runs the code you mention as the anonymous function after the timer expires, WRONG, it does not run the passed callback immediately after however many seconds you passed to it as long as the event queue is not empty
TRUE! I agree with what you say. Its not practical to explain all the gory details of async to someone who is still trying to understand the basics first.
What @Dummy said isn't the "gory" part, it's a very important detail that explains the basics of JS.
@Rewire: Please feel free to explain it in detail as an answer :)
I never said I want the flow, I want to understand how JS handles this written piece of code which @Arseniy-II has explained properly.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.