Why does a setTimeout delay of 0 still run after all other synchronous code in a for loop?

假如想象 提交于 2020-03-05 05:06:12

问题


I've know versions of this question has been discussed, and I think this is unique. Why does a delay of 0, still causes the below behavior.

for(var i = 0; i <3; i ++) {
  console.log(i, 'started');
  setTimeout(()=> {
    console.log(i);
  },0)
  console.log(i, 'done');
}

console.log('loop over');

   // 0 started
   // 0 done
   // 1 started
   // 1 done
   // 2 started
   // 2 done
   // loop over
   // 3 3 3 

Here is what I think I know so far:

Quoted from MDN in respect to setTimeouts position on the stack:

This is because even though setTimeout was called with a delay of zero, it's placed on a queue and scheduled to run at the next opportunity; not immediately. Currently-executing code must complete before functions on the queue are executed, thus the resulting execution order may not be as expected.

Am I correct in saying the for-loop and any synchronous code is placed on the call stack before setTimeout, AND even if you set the delay to 0, setTimeout will always run only after the for-loop has completed? Otherwise, why would a delay of 0, still result in the above behavior?

Thanks!

EDIT:

After getting started in the right direction, I found a few videos and a nice little tool that shows you the event loop and how it relates to this example code. Here is the JS runtime simulator: loupe


回答1:


JavaScript, both in the browser and on the server, runs as an event loop. The runtime is constantly polling for events. Events consist of user actions (e.g. DOM element x was clicked), I/O (data came back from I/O or ajax call), and timer events (in this case). setTimeout(fn, 0) simply adds an event to be processed by the event loop at minimum when 0 milliseconds have elapsed. It will always execute after the current event has been processed.




回答2:


Am I correct in saying the for-loop and any synchronous code is placed on the call stack before setTimeout

To be pedantic, setTimeout() itself gets called synchronously, and placed on the callstack right after console.log(i, 'started'); . It's the settimeout callback (in your case console.log(i)) that gets queued and called asynchronously.



来源:https://stackoverflow.com/questions/49331947/why-does-a-settimeout-delay-of-0-still-run-after-all-other-synchronous-code-in-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!