2013-01-16 72 views
2

我試圖圍繞我的頭,瞭解javascript異步如何在單線程瀏覽器環境中工作。在瀏覽器中的javascript:異步任務執行模型

由於異步,我們可以同時處理定時器和xhr請求。 現在假設我有類似下面

function doStuff() { 
    for(var i=0; i<100000000; i++) { 
     // do something to make proc busy 
     if(i%1000 === 0) { 
      console.log('in for loop'); 
     } 
    } 
} 


setTimeout(function() { 
    console.log('timed out') 
}, 2); 
doStuff(); 
doStuff(); 
doStuff(); 

定時器設置爲非常小的值(2ms的),所以我想它應該工作如下:

1)計時器回調排隊

2 )doStuff()被執行(作爲一個整體?),它需要一些

3)定時器的回調運行時間(多於那些2毫秒),因爲這裏提供時刻betweet一個doStuff()執行與另一

4)未來doStuff()被稱爲

4)最後doStuff()被稱爲

我看到的卻是,所有這三個doStuff()事情之前計時器回調火災完成。而且它比那些2ms的時間要長得多。是的,我知道這個時間值設定在setTimeout不能保證。

我的問題是javascript如何執行代碼?什麼是在異步隊列被調用之前一次執行的最小的原子塊?

回答

5

你錯在這裏:

3)計時器回調運行是有片刻betweet一個doStuff()執行和其他

的原因是在回答以下問題:

什麼是在異步隊列被調用之前一次執行的最小原子塊?

JavaScript使用的東西叫做事件循環。每個事件循環週期都可以稱爲「滴答」。在每次打勾時,解釋器檢查是否執行異步回調(例如,在超時已到期的setTimeout回調)。

所有其他同步操作發生在同一個tick中。因此,以您爲例,將在下一個勾號中檢查計時器是否到期,但在當前的勾號中執行對doStuff的所有三個調用。這就是爲什麼傳遞到setTimeout的時間值不能保證:沒有辦法知道需要多長時間才能進行下一個計時,所以我們通常會說回調將「儘快」運行。在setInterval的情況下,一些呼叫甚至可能被丟棄;例如,當下一個滴答發生兩次定義的時間間隔時,回調只運行一次。

3

由於Javascript是單線程的,超時只能在解釋器空閒時才能處理。當你排隊超時功能時,解釋器仍然在處理你的主腳本,並且將不能處理超時直到它完成。

setTimeoutsetInterval或任何其他異步事件將僅在沒有代碼運行時處理。他們不會中斷當前的代碼。任何運行的JavaScript代碼塊都會延遲所有事件處理程序的執行。

0

WebWorker是Async Javascript的更新解決方案。對於sencha開發者here是教程,仍然不依賴於setTimeout