setTimeout( function(){ alert(’你好!’); } , 0); setInterval( callbackFunction , 100);
同理對setInterval的callbackFunction方法每間隔100毫秒就當即被執行深信不疑!
div.onclick = function(){ setTimeout( function(){document.getElementById(’inputField’).focus();}, 0); };
setTimeout( function(){ while(true){} } , 100); setTimeout( function(){ alert(’你好!’); } , 200); setInterval( callbackFunction , 200);
<strong>JavaScript引擎是單線程運行的,瀏覽器不管在何時都有且只有一個線程在運行JavaScript程序.
</strong>
JavaScript引擎用單線程運行也是有意義的,單線程沒必要理會線程同步這些複雜的問題,問題獲得簡化
那麼單線程的JavaScript引擎是怎麼配合瀏覽器內核處理這些定時器和響應瀏覽器事件的呢?下面結合瀏覽器內核處理方式簡單說明html
瀏覽器內核實現容許多個線程異步執行,這些線程在內核制控下相互配合以保持同步。假如某一瀏覽器內核的實現至少有三個常駐線程:javascript引擎線程,界面渲染線程,瀏覽器事件觸發線程,除些之外,也有一些執行完就終止的線程,如Http請求線程,這些異步線程都會產生不一樣的異步事件,下面經過一個圖來闡明單線程的JavaScript引擎與另外那些線程是怎樣互動通訊的,雖然每一個瀏覽器內核實現細節不一樣,但這其中的調用原理都是大同小異java
因此,在腳本中執行對界面進行更新操做,如添加結點,刪除結點或改變結點的外觀等更新並不會當即體現出來,這些操做將保存在一個隊列中,待JavaScript引擎空閒時纔有機會渲染出來。ajax
同理,仍是在t1時間段內,接下來某個setInterval定時器也被添加了,因爲是間隔定時,在t1段內連續被觸發了兩次,這兩個事件被排到隊尾等待處理。
若是隊列非空,引擎就從隊列頭取出一個任務,直到該任務處理完,即返回後引擎接着運行下一個任務,在任務沒返回前隊列中的其它任務是無法被執行的.
相信您如今已經很清楚JavaScript是否可多線程,也理解JavaScript定時器運行機制了,下面咱們來對一些案例進行分析編程
案例1:setTimeout與setInterval瀏覽器
setTimeout(function(){ /* 代碼塊... */ setTimeout(arguments.callee, 10); }, 10); setInterval(function(){ /*代碼塊... */ }, 10);
這兩段代碼看一塊兒效果同樣,其實非也多線程
第一段中回調函數內的setTimeout是JavaScript引擎執行後再設置新的setTimeout 定時(此時會把代碼插入任務隊列),假定上一個回調處理完到下一個回調開始處理爲一個時間間隔,理論兩個setTimeout回調執行時間間隔>=10ms。setTimeout好處就是嚴格保證每隔一段時間執行代碼。異步
第二段自setInterval設置定時後,定時觸發線程就會源源不斷的每隔十秒產生異步定時事件並放到任務隊列尾,理論上兩個setInterval 回調執行時間間隔<=10,這就可能致使上一段代碼執行完畢後當即執行下一段代碼,不會出現想象中的間隔一段時間再執行編程語言
其實請求確實是異步的,不過這請求是由瀏覽器新開一個線程請求(參見上圖),當請求的狀態變動時,若是先前已設置回調,這異步線程就產生狀態變動事件放到 JavaScript引擎的處理隊列中等待處理,當任務被處理時,JavaScript引擎始終是單線程運行回調函數,具體點即仍是單線程運行 onreadystatechange所設置的函數.
setTimeout(function(a,b,c){ console.log(a);//a console.log(b);//b console.log(c);//c },0,3,4,5); setInterval(function(a,b,c){ console.log(a);//b console.log(b);//b console.log(c);//c },0,3,4,5);