admin管理员组

文章数量:1401772

In the below code I run 2 sets of tests where a timer is either split in 2 nested calls to setTimeout() and a single call with the timeout set to the sum of both previous calls.

However, I notice that the ordering isn't the same when the summed up timer is 30ms and when it's 50ms:

setTimeout(() => {
    setTimeout(() => {
        console.log("Timeout 1 (40+10ms)");
    }, 10);
}, 40);

setTimeout(() => {
    console.log("Timeout 2 (50ms)");
}, 50);


setTimeout(() => {
    setTimeout(() => {
        console.log("Timeout 1 (20+10ms)");
    }, 10);
}, 20);

setTimeout(() => {
    console.log("Timeout 2 (30ms)");
}, 30);

In the below code I run 2 sets of tests where a timer is either split in 2 nested calls to setTimeout() and a single call with the timeout set to the sum of both previous calls.

However, I notice that the ordering isn't the same when the summed up timer is 30ms and when it's 50ms:

setTimeout(() => {
    setTimeout(() => {
        console.log("Timeout 1 (40+10ms)");
    }, 10);
}, 40);

setTimeout(() => {
    console.log("Timeout 2 (50ms)");
}, 50);


setTimeout(() => {
    setTimeout(() => {
        console.log("Timeout 1 (20+10ms)");
    }, 10);
}, 20);

setTimeout(() => {
    console.log("Timeout 2 (30ms)");
}, 30);

In my Chrome browser I get for the 50ms timer

  • Timeout 1 (40+10ms)
  • Timeout 2 (50ms)

While for the 30ms one, I get

  • Timeout 2 (30ms)
  • Timeout 1 (20+10ms)

Aren't these supposed to be the same?
Why does only changing the time in delay produces a different order?

Share Improve this question edited Mar 24 at 2:07 Kaiido 138k14 gold badges259 silver badges324 bronze badges asked Mar 23 at 21:16 Artem_3elt3erArtem_3elt3er 393 bronze badges 0
Add a comment  | 

3 Answers 3

Reset to default 3

Per specs, the ordering is not defined in this case. They do ask to wait for previous invocations that had a smaller timeout to be executed first, but here we're in the undefined case of a smaller timer that's been set later. So both orders are allowed.

Now, if Chrome switches the ordering specifically at 32ms, it's because of this CL. According to the comments in the code there, that would be to accommodate with some tests they were running for removing 1ms clamping in setTimeout(, 0). The logic exposed in the comments read:

// A timer with a long timeout probably doesn't need to run at a precise time,
// so allow some leeway on it. On the other hand, a timer with a short timeout
// may need to run on time to deliver the best user experience.

Though it seems they were supposed to remove this logic once the experiments would be over (which I believe they are).

tested this on node it got this:

Timeout 2 (30ms)
Timeout 1 (20+10ms)
Timeout 2 (50ms)
Timeout 1 (40+10ms)

but in the browser get the same result of you,i think that you touched an indetermined irea because it really depends on the event loop environement in node i guess this is the correct one because in the inner setTimeout when executing it we add some slight delay so it (when registering the inner setTimeout) and also in the manner the second timeout is executed after the first so it really dependes on the actuale environement state,not sure but wish this can help you

see setTimeout(function, milliseconds, param1, param2, ...)

It seems that the two times are initialized together and the countdown begins. then 10ms ends and exits, but there are 10ms left of the 20ms and only then does it end, that's what I understood.

本文标签: javascriptDifferent order for timers when spliting in 2 calls or in a singleStack Overflow