JavaScript單線程/瀏覽器事件驅動

首先看一個例子:

function foo() {
  console.log('first');
  setTimeout((function(){
    console.log('second');
  }),5);
}
for(var i =0;i<10000;i++) {
  foo();
}

結果是先輸出10000個first然後立即輸出10000個second。

因爲JavaScript是單線程運行的,特定的時間只能有特定的代碼正在執行,不會有多段代碼同時執行。

setTimeout一般文檔中的描述是一段時間後執行某段代碼或者方法,但是嚴格說來不是的,應該是一段時間後把某段代碼或者方法放入執行隊列中,至於什麼時候能執行它們就只能等JavaScript引擎按照隊列一個一個進行。

上面的例子,setTimeout中的方法只能等待for循環結束後才執行,因爲for循環在執行隊列中靠前。


但是瀏覽器卻不是單線程的,一個瀏覽器可能有以下進程:javascript引擎線程、界面渲染線程、瀏覽器事件觸發線程、Http請求線程。而且瀏覽器依靠事件驅動機制來確定代碼的執行隊列。

所以就不難理解爲什麼AJAX是異步操作的了。

由於JavaScript是單線程的,所以儘管瀏覽器可以並行下載js文件,但是也必須依次順序下載。

實現非阻塞的js文件下載有兩種方法:

1. HTML5的defer和async。

<script type="text/javascript" defer src="foo.js"></script>
<script type="text/javascript" async src="foo.js"></script>

2. 動態加載js文件

var script=document.createElement('script');
script.setAttribute("type","text/javascript");
script.setAttribute("src","xxx.js");
document.documentElement.appendChild(script);
//or: document.getElementsByTagName('head')[0].appendChild(script);
//or: document.body.appendChild(script);



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章