1. 程式人生 > >JavaScript的單執行緒與阻塞式執行(附案例)

JavaScript的單執行緒與阻塞式執行(附案例)

轉:JavaScript是單執行緒執行的,無法同時執行多段程式碼。當某一段程式碼正在執行的時候,所有後續的任務都必須等待,形成一個佇列。一旦當前任務執行完畢,再從佇列中取出下一個任務,這也常被稱為 “阻塞式執行”。所以一次滑鼠點選,或是計時器到達時間點,或是Ajax請求完成觸發了回撥函式,這些事件處理程式或回撥函式都不會立即執行,而是立即排隊,一旦執行緒有空閒就執行。關鍵說明:假如當前 JavaScript執行緒正在執行一段很耗時的程式碼,此時發生了一次滑鼠點選,那麼事件處理程式就被阻塞,使用者也無法立即看到反饋,事件處理程式會被放入任務佇列,直到前面的程式碼結束以後才會開始執行。如果程式碼中設定了一個 setTimeout,那麼瀏覽器便會在合適的時間,將程式碼插入任務佇列,如果這個時間設為 0,就代表立即插入佇列,但不是立即執行,仍然要等待前面程式碼執行完畢。所以 setTimeout 並不能保證執行的時間,是否及時執行取決於 JavaScript 執行緒是擁擠還是空閒。

以上用於解釋下面的程式碼,理解的關鍵就是“阻塞式執行”程式碼源自《javascript設計模式與開發實踐》:

<body>
<input type="checkbox" id="1"></input>1
<input type="checkbox" id="2"></input>2
<input type="checkbox" id="3"></input>3
<input type="checkbox" id="4"></input>4
<input type="checkbox" id="5"></input>5
<input type="checkbox" id="6"></input>6
<input type="checkbox" id="7"></input>7
<input type="checkbox" id="8"></input>8
<input type="checkbox" id="9"></input>9
</body>
<script>


var timeWait =function(){
for(var i=0;i<100000000;i++){

}
}
var synchronousFile =function(id){
console.log("開始同步檔案,id為:"+id);
for(var i=0;i<100;i++){
timeWait();
}
console.log("同步檔案結束");
}
var proxySynchronousFile =(function(){
var cache=[],timer;
return function(id){
console.log(id,timer);
cache.push(id);
if(timer){
return;
}
timer =setTimeout(function(){
synchronousFile(cache.join(","));
clearTimeout(timer);
timer=null;
cache.length=0;
},2000);
}
})();
var checkbox = document.getElementsByTagName( 'input' );
for ( var i = 0, c; c = checkbox[ i++ ]; ){
c.onclick = function(){
if ( this.checked === true ){
proxySynchronousFile( this.id );
}
}
};
</script>