0

My question is: why function results appears before for loop in browser console? It should run for loop (1, 2, 3, 4, 5), but it run ('cool' and 1!2!3) first, so below I add my code and console result. I'll be very thankful if someone can explain me this behaviour. It is not a duplicate, because, I want to understand how it works, not to make it work. In suggested question there is a solutions to run for loop with setTimeout first, but not explain behaviour completely.

// Loops + Closure
for (let i = 1; i <= 5; i++) {
    setTimeout(function timer() {
        console.log(i)
    }, i * 1000)
}

//Modules
function CoolModule() {
    let something = 'cool'
    let another = [1, 2, 3]

    function doSomething() {
        console.log(something)
    }

    function doAnother() {
        console.log(another.join('!'))
    }

    return {
        doSomething: doSomething,
        doAnother: doAnother
    }
}

let foo2 = CoolModule()

foo2.doSomething() // 'cool'

foo2.doAnother() // 1 ! 2 ! 3

console result

BlackB0ne
  • 135
  • 1
  • 10
  • 1
    Because the for loop fires up a bunch of timers that don't output anything until they expire? I'm not sure why you'd expect anything different. – Dave Newton Feb 18 '17 at 17:06
  • 2
    Isn't it obvious? `setTimeout` starts off with a delay of 1 second. The rest of the code runs in less than a second –  Feb 18 '17 at 17:06
  • 4
    Are you possibly confused by what setTimeout does? It doesn't block execution. – Dave Newton Feb 18 '17 at 17:08
  • @Amy - if it were obvious, the OP wouldn't be asking. It might be obvious to you and me, but the question is a valid one. – Mitya Feb 18 '17 at 17:11
  • Possible duplicate of [Javascript - Wait 5 seconds before executing next line](http://stackoverflow.com/questions/14226803/javascript-wait-5-seconds-before-executing-next-line) – JJJ Feb 18 '17 at 17:22

1 Answers1

0

JavaScript works by running blocks of code one after the other. So you have one block of code that starts with the for loop and ends with foo2.doAnother(). But the calls to setTimeout don't run the code immediately -- they put new blocks of code in the queue -- the console.log(i) blocks. So your code works more like;

  1. Put five 'timer' functions in the queue. Each one must wait 1s, 2s, 3s, etc before it's executed, and each must execute after the current block.
  2. Execute the 'CoolModule' code.
  3. (the code you wrote finishes executing)
  4. (wait 1s)
  5. run the first instance of timer()
  6. (wait another 1s)
  7. run the second instance of timer()
  8. etc...
Steve Cooper
  • 20,542
  • 15
  • 71
  • 88
  • So, it's special behaviour of setTimeout() which waits everything to execute in block then start its work? – BlackB0ne Feb 19 '17 at 10:21
  • Yeah -- setTimeout says 'run this function later' -- it puts the function in a work queue. But before it does anything in the queue, it finishes running the rest of the code. – Steve Cooper Feb 19 '17 at 19:45