Adison Masih
Adison Masih

Reputation: 824

setTimeout callbacks don't run in the expected order

Consider this piece of code:

Promise.race([
    new Promise(_ => setTimeout(() => _("first one"), 999.1)),
    new Promise(_ => setTimeout(() => _("second one"), 999)),
]).then(console.log)

Nothing Fancy Here. Its A Simple Promise.race which as far as i know:

Takes In An Iterable Of Promises and returns the value of the promise which resolves first.

According to the above definition, the second promise should resolve first as it has a 0.1 less delay than the first one.

So The Expected output should be: second one

But strangely, the actual result is first one

Why is this so? is there something i'm missing or rather misinterpreting?

Upvotes: 1

Views: 70

Answers (1)

Thomas Zimmermann
Thomas Zimmermann

Reputation: 1967

This is almost certainly browser-dependent as setTimeout is not part of ECMAScript. If you test it out you can realise that it has the same behaviour for 999.9ms and then works correctly if you input 1000ms. My take on this one is that setTimeout truncates the number somewhere between our browser implementation and the lower levels, and has to run synchronously at least at some time, meaning that Promise.race([a, b]) will run a before b and resolve a before b if this is two operations with equal duration.

Interesting quote from Timothy Strimple you can find here

What happens is you've got essentially a dictionary of timeouts at the top level, so all 100ms timeouts are grouped together. Whenever a new timeout is added, or the oldest timeout triggers, it is appended to the list. This means that the oldest timeout, the one which will trigger the soonest, is at the beginning of the list. There is a single timer for this list, and it's set based on the time until the first item in the list is set to expire.

If you call setTimeout 1000 times each with the same timeout value, they will be appended to the list in the order you called setTimeout and no sorting is necessary. It's a very efficient setup.

Upvotes: 3

Related Questions