latentflip / loupe

Visualizing the javascript runtime at runtime

Home Page:http://latentflip.com/loupe

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Problem with setInterval and setTimeout

asaadsaad opened this issue · comments

This code will give wrong results! not only setInterval issues but it will run f1 before f4!
setTimeout(function f1(){console.log(1)}, 500);
console.log(2);
var intId = setInterval(function f3(){console.log(3)}, 0);
setTimeout(function f4(){console.log(4)}, 0);
console.log(5);
clearInterval(intId);

Based on Philip explanation, setInterval will at least push a callback function f3() to the queue at least once (async) before the clearInterval clear it from the WebAPI, but in real browser f3 will never run, so basically WebAPI will not start working on what we push to it until we finish the Stack!

f1 running before f4 is a necessary result of the delays that the app adds. We insert a 0.5 second delay between each step to allow you to see what's going on. If you increase the timeout of f1 you should see that it runs correctly.

This is equivalent in non delayed code to doing:

setTimeout(f1, 1);
// some stuff
setTimeout(f4, 0);

if you did that you'd see f1 before f4

The interval issue is most likely a bug with my instrumentation code, as it's effectively emulating the browser behaviour, rather than using it directly. I'm probably not running clearInterval properly at all I suspect.

Thank you very much! I did increase the timeout of f1 and it runs correctly.

I'll try to read the code sometime to figure out the interval issue!

In the video and experience, setTimeout() is a function of window and include in the Web Apis. And I have a question,when setTimout(()=>, time) is waiting during time,whether is controlled by a browser thread,otherwise which part know the time has finished and push in the queue?

Are you sure this loupe works correctly? I read explanation above but)

setTimeout(function timeout() {
    console.log("Timeout 1");
}, 3000); // or 300

setTimeout(function timeout() {
    console.log("Timeout 2");
}, 1000); // or 100

setTimeout(function timeout() {
    console.log("Timeout 3");
}, 2000); // or 200

setTimeout(function timeout() {
    console.log("Timeout 4");
}, 1000); // or 100

I always get this sequence in the browser (Chrome). It's logical and correctly:

Timeout 2
Timeout 4
Timeout 3
Timeout 1

3s 1s 2s 1s But here is not correctly:

Timeout 2
Timeout 1
Timeout 3
Timeout 4

0.3s 0.1s 0.2s 0.1s Here is different and not correctly:

Timeout 1
Timeout 2
Timeout 3
Timeout 4
  console.log('this is the start');

  setTimeout(function cb1() {
    console.log('this is a msg from callback 1');
  });

  console.log('this is just a message');

  setTimeout(function cb2() {
    console.log('this is a msg from callback 2');
  }, 0);

  console.log('this is the end');

Is it correctly works with setTimeout without 2nd argument (delay)? WebApis stores cb2() after finish.
If I have both setTimeout with 180 ms delay I will see both in WebApis after finish. But if 1st timeout has 180ms and 2nd timeout has 400ms I will see only cb1 in webApis. example