2013-06-22 13 views
4

JavaScript的setTimeout函數是使我重新評估我所知道的JavaScript小。今天早些時候,我遇到了一個像這樣的循環:瞭解線程/同步性通過JS的setTimeout的

for (i = 0; i < length; i++) { 
    setTimeout(executeOtherCode, 5000) 
} 

我預計這個代碼做的是執行executeOtherCode功能,「休眠」 5秒鐘,然後繼續下一個迭代。相反,我得到的是同時執行長度時間的executeOtherCode。

所以從我的理解,setTimeout的是一個異步函數調用。它是否正確?然而,如果我要執行一個常規函數,我們將其稱爲hugeFunction(),這需要1分鐘的時間來執行,下一行代碼將不會執行,直到該函數返回一些東西,是正確的?那麼爲什麼這兩個不同呢?只是語言設計的選擇?

我見過的jQuery等功能,在類似asyncrhonous的行爲方式,喜歡的getJSON。這只是一個知道哪些函數被定義爲異步的問題,或者是否存在某種識別它們的模式?如果是這樣,什麼?

+0

通常,異步函數是處理通過網絡檢索數據或某種I/O操作(例如,新的IndexedDB中的某些方法以及HTML5的WebWorkers功能)的函數。除此之外,沒有真正一致的方法來識別它們;你只需要看看你正在使用的庫的文檔。 –

+1

_「相反,我得到的是同時執行其他代碼」_ - 否,你沒有。該代碼在5000ms之後排隊'executeOtherCode()'被調用'length'時間,同時當前塊繼續。每個超時在儘可能接近5000ms後啓動_但不是在其他JS正在執行時,_因此每個超時都是一個接一個地執行,而不是同時執行,而不是多線程。它似乎是同時發生的,因爲它們之間沒有明顯的延遲。 – nnnnnn

回答

6

一般來說,特殊情況除外 - 的JavaScript執行同步和秩序。

setTimeout(executeOtherCode, 5000) 

告訴「在5秒內運行功能executeOtherCode」。它繼續運行循環,它不會'阻止'執行。

在5秒鐘內,事件循環將會注意到一個定時器(以及定時器),它們將被執行(一個接一個地執行)。

如果你想要的功能,以在對方5秒延遲執行,你需要告訴一個函數的最後一個完成後執行5秒,這種模式被稱爲異步信號。

一般的經驗法則是,如果它的I/O,它應該是異步,這就是爲什麼AJAX是異步的(以及其他HTTP請求像腳本標記注入)和交互事件是異步的(JavaScript的反應以點擊爲例,它不會等待它們)。定時器(setTimeout和setInterval也是異步的)。

其他的一切是同步的。

現在有些功能可能會使用這些其他功能,但there is no silver bullet在找出哪個是哪個。只要清楚文件。大多數異步函數都有一個回調參數(如executeOtherCode的第一個參數),但有些函數沒有,有些函數接受回調但不是異步。

+0

+1。大多數JavaScript以單線程方式執行(HTML5 WebWorkers除外) –