1

Can someone explain me that:

const array = [0, 1, 2, 4, 8, 16, 32, 16, 8, 4, 2, 1, 0];

for (let i = 0; i < array.length; i++) {
    setTimeout(function () {
        console.log(array[i]);
    }, array[i])
}

Why this return 0 1 1 0 2 2 4 4 8 8 16 16 32, instead of array items one by one?

11
  • 3
    Possible duplicate of setTimeout in for-loop does not print consecutive values Commented Oct 6, 2018 at 14:08
  • 1
    @GeorgeJempty Not a duplicate. OP uses let. Commented Oct 6, 2018 at 14:10
  • 2
    The delays are all different based on value of array[i]. What exactly are you wanting to accomplish? Commented Oct 6, 2018 at 14:13
  • 1
    It makes a difference that let binds to a separate value when it is inside a closure. Using var would cause undefined to be printed because at the time it logs, it the i will be equal to the array lenght. (And since, arrays are zero-based, will try to fetch an element that is not there.) Commented Oct 6, 2018 at 14:21
  • 4
    The problem here is just that the timeout length is the value of the element, so of course the higher values are logged later, because the timeout is longer. Commented Oct 6, 2018 at 14:22

4 Answers 4

5

The numbers are appearing one after another. However you won't be able to see that because you have set a very low delay between them. Some of them will appear together. Those are the ones having the same value for array[i].

For better seeing the delay between them, I would suggest replacing array[i] by array [i] * x, where x is a number. Look at this:

const array = [0, 1, 2, 4, 8, 16, 32, 16, 8, 4, 2, 1, 0];

for (let i = 0; i < array.length; i++) {
    setTimeout(function () {
        console.log(array[i]);
    }, array[i] * 500)
}

0 will be echoed after 0 × 0.5 = 0 seconds.

1 will be echoed after 1 × 0.5 = 0.5 seconds.

2 will be echoed after 2 × 0.5 = 1 seconds.

4 will be echoed after 4 × 0.5 = 2 seconds, and so on.

EDIT: If you are asking about the reason why 0 1 1 0 is logged instead of 0 0 1 1, it is likely because the computer takes some small time looping through the array, and before it reaches the final "0", 1 millisecond would have passed, so it will be time to log "1" and "1". Notice that increasing the delay between the logs solves the problem.

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

1 Comment

Numbers are not appearing one after another(just run code snippet that Mateusz Daniluk provided and look at result) - in case of first 4 (0,1,1,0) the order is changed.
0

When setTimeout()-ing, 0 and 1 mean practically the same thing for a browser (that's why your zeros and ones are mixed at the beginning). All the other numbers are correctly showing up with the delay you're giving them, so first the smallest (and they get scheduled first), then the 2, 4, etc, these will appear later (only a very little bit later) on the console. If you slow this thing down, as @WaisKamal suggested, this timed order will be obvious. So by the time your second zero appears, all the other outputs are already scheduled (that is, setTimeouts themselves all happened, in the order of the array), and then they run in the order of timing.

Comments

0

Your code should log array elements in increasing order:

0,0,1,1,2,2,3,3,4,4,16,16,32.

And it would if you changed timeout to larger values:

const array = [0, 100, 200, 400, 800, 1600, 3200, 1600, 800, 400, 200, 100, 0];

for (let i = 0; i < array.length; i++) {
    setTimeout(function () {
        console.log(array[i]);
    }, array[i])
}

The reason why your code doesn't work as expected is order in which setTimeout callbacks are executed.

You can think of it this way - after timeout defined in setTimeout has passed the callback is added to the some kind of queue, that runs it as quickly as possible(remember that js is single threaded). In your case callback for last element of array is added to that queue after callback for first, second and third element(because your loop execution takes more than 1 millisecond).

Comments

0

It is because the execution of the loop , is faster than your setTimeout function delay, so that's why the number with minimum delay executes first.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.