JS 同步與非同步程式設計
JS同步與非同步程式設計
JS是單執行緒的, js就是個傻子, 腦子一根筋, 做著當前的這件事情, 沒有完成之前絕不會做下一件事情
JS中的兩種程式設計思想
同步
上一件事情沒有完成, 繼續處理上一件事情, 只有上一件事情完成了, 才會做另一件事情(JS中大部分都是同步程式設計的)
for(var i = 0; i < 10000; i ++){
if i == 9999(){
console.log("迴圈結束了~~")
}
console.log("ok")
}
-> 迴圈結束了~~
-> ok
for迴圈就是同步程式設計的, 只有迴圈結束後, 才會繼續執行下面的程式碼
while(1){
}
console.log("ok")
永遠都不會執行 console.log("ok"), 因為上面的迴圈是死迴圈, 永遠都不會結束
非同步
規劃要做一件事情, 但是不是當前立馬去執行這件事情, 需要等一定的時間, 這樣的話, 我們不會等著它執行, 而是繼續執行下面的操作, "只有當下面的事情都處理完成了", 只有當下面的事情都處理了, 才會返回頭處理之前的事情; 如果下面的事情並沒有處理完成, 不管之前的事情有沒有到時間, 都踏踏實實的給我等著
實現方法
在JS中非同步程式設計只有四種情況:
- 定時器都是非同步程式設計的
- 所有的事件都是非同步程式設計的
- Ajax讀取資料的時候, 我們一般都設定為非同步程式設計
- 回撥函式也都是非同步程式設計的
定時器
var n = 0;
window.setTimeout(function(){
n++;
console.log(n);
}, 1000);
console.log(n);
-> 0
-> 1
不立即執行
每一個瀏覽器對於定時器的等待時間都有一個最小的值, 谷歌:5~6ms IE:10~13ms, 如果設定的等待時間小於這個值, 不起作用, 還是需要等到最小時間才執行; 尤其是寫0也不是立即執行.
var n = 0;
window.setTimeout(function(){
n++;
console.log(n);
}, 0);
console.log(n);
-> 0
-> 1
不保證準確的執行時間
我們定時器設定的等待時間不一定就是最終執行的時間, 如果定時器之後還有其他的事情正在處理中, 不管定時器的時間有沒有到, 都是不會執行定時器的
var n = 0;
window.setTimeout(function(){
n++;
console.log(n);
}, 0);
console.log(n);
while(1){
n++
}
console.log(n)
-> 0
進入死迴圈, 瀏覽器卡死
任務佇列
var n = 0;
window.setTimeout(function (){
n += 2;
console.log(n)
}, 2);
window.setTimeout(function (){
n += 5;
console.log(n)
}, 1);
console.log(n);
for(var i =0; i < 10000000; i++){
}
console.log(n);
-> 0
-> 0
-> 5
-> 7
任務佇列
任務佇列池
任務 -> 2ms執行
將任務->1ms執行新增到佇列池中, 發現時間更短的在任務佇列中提前排列
任務 -> 1ms執行
任務 -> 2ms執行
執行區
var n = 0;
console.log(n); ->0
執行一千萬次的迴圈, 可能消耗的時間大於20ms也可能小於20ms
console.log(n) -> 0
此時的立即執行的任務都完成了
返回頭
開始按照任務池中的任務佇列的順序開始從上到下執行.
事件
for(var i=0; i<oLis.length;i++){
oLis[i].onclick = function(){
console.log(i);
}
}
-> 3
-> 3
-> 3
使用者點選的時候, 迴圈已經執行完了, i已經變成了3.