DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> JavaScript基礎知識 >> setTimeout和setInterval的深入理解
setTimeout和setInterval的深入理解
編輯:JavaScript基礎知識     
大概半年前發表過一篇關於setTimeout和setInterval的文章,但是現在回去仔細一看發現其實存在很多不足以及錯誤。事實上,setTimeout和setInterval並沒有我們字面上理解的那麼簡單。要真正掌握並理解這兩個方法,還得從javascript的單線程機制說起。

【開門見山】setTimeout和setInterval是如何工作的呢?
我們知道,js是單線程執行的。所以其實setTimeout和setInterval所謂的“異步調用”事實上是通過將代碼段插入到代碼的執行隊列中實現的。

而如何計算插入的時間點呢?自然是要用到我們所說的timer,也就是計時器。當執行setTimeout和setInterval的時候,timer會根據你設定的時間“准確”地找到代碼的插入點。當隊列“正常”地執行到插入點時,就觸發timer callback,也就是我們設定的回調函數:
復制代碼 代碼如下:
function fn() {
/*
here is some codes
*/
setTimeout(function() {alert('ok!')},1000);
}

上面這個例子就是我們通常的用法,應該容易理解。可是,timer真的能那麼准確麼?代碼隊列的執行真的能那麼正常麼?

【斬草除根】重新認識所謂的“異步”
剛剛已經知道,事實上setTimeout和setInterval只是簡簡單單地通過插入代碼到代碼隊列來實現代碼的延遲執行(或者說異步執行)。但是事實上所謂的異步只是一個假象——它同樣運行在一個線程上!
那麼問題就來了,要是在代碼插入點前的代碼執行時間超過了傳入setTimeout或setInterval的設定時間會怎樣呢?讓我們來看看這段代碼:
復制代碼 代碼如下:
function fn() {
setTimeout(function(){alert('can you see me?');},1000);
while(true) {}
}

你覺得這段代碼的執行結果是什麼呢?答案是,alert永遠不會出現。
這是為什麼呢?因為,while這段代碼沒有執行完,插入在後面的代碼便永遠不會執行。
綜上所述,其實JS終歸是單線程產物。無論如何“異步”都不可能突破單線程這個障礙。所以許多的“異步調用”(包括Ajax)事實上也只是“偽異步”而已。只要理解了這麼一個概念,也許理解setTimeout和setInterval也就不難了。
XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved