<script> for(var i=0;i<2;i++){ setTimeout(function(){ console.log(i); },0); } </script> // 結果:2,2
js同步異步執行順序setTimeOut面試題分析:html
打印兩個2而不是0,1,跟js執行順序有關係。面試
全部的任務分爲兩種,一種是同步任務,一種是異步任務。同步任務是指在主線程上排隊的任務。異步任務是指不進入主線程、而進入"任務隊列"(task queue)的任務,只有"任務隊列"通知主線程,某個異步任務能夠執行了,該任務纔會進入主線程執行。異步
(1)全部同步任務都在主線程上執行,造成一個執行棧(execution context stack)。函數
(2)主線程以外,還存在一個"任務隊列"(task queue)。只要異步任務有了運行結果,就在"任務隊列"之中放置一個事件。oop
(3)一旦"執行棧"中的全部同步任務執行完畢,系統就會讀取"任務隊列",看看裏面有哪些事件。那些對應的異步任務,因而結束等待狀態,進入執行棧,開始執行。spa
詳情看阮一峯JavaScript運行機制。連接:http://www.ruanyifeng.com/blog/2014/10/event-loop.html線程
setTimeOut函數爲異步任務,for循環爲同步任務,setTimeOut裏的函數爲回調函數。執行順序爲:同步優先,異步靠邊,回調墊底。因此即便setTimeOut的時間參數是0依然會放到任務隊列裏,而不是主線程。主線程執行完for循環之後才執行異步任務setTimeOut。另外setTimeout()只是將事件插入了"任務隊列",必須等到當前代碼(執行棧)執行完,主線程纔會去執行它指定的回調函數。要是當前代碼耗時很長,有可能要等好久,因此並無辦法保證,回調函數必定會在setTimeout()指定的時間執行。code
<script> for(var i=0;i<2;i++){ (function(){ console.log(i); }(i)) } </script>
// 結果:0,1
裏邊換成當即執行函數,則會打印0,1.htm