這兩個應該大家都認識,我也就不多解釋了。今天發現了一個很經典的例子,看下
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
先說下這個不是問你的打印的是什麼,是5個5沒錯,但是是每隔1秒輸出一個5 ?還是一秒後立即輸出5個5?
答案:一秒後立即輸出5個5
setTimeout執行時:定時觸發器線程、事件觸發線程、JS引擎線程在幹什麼?
每個setTimeout都由定時觸發器線程負責計時,計時完畢後,添加到事件隊列中(即:事件觸發線程),等待JS引擎線程空閒後,再來依次執行。
爲什麼一秒後立即輸出5個5?
首先JS引擎線程 要運行for循環,在每次循環中都會調用一個setTimeout函數,每個setTimeout計時結束後都會將其回調函數添加到 事件隊列 中。等for循環結束後(即JS引擎線程空閒後),纔開始按順序執行事件隊列中的函數。
每次循環都會在一秒後將回調函數添加到事件隊列中,但由於兩次相鄰的循環時間是短到可以忽略不計的,所以表面看上去 一秒後立即執行了5次回調函數,即一秒後立即輸出5個5。
setInterval有兩個缺點:
使用setInterval時,某些間隔會被跳過
;可能多個定時器會連續執行
;
在前一個定時器執行完前,不會向隊列插入新的定時器
- 保證定時器間隔
setInterval(function, N) //即:每隔N秒把function事件推到消息隊列中 並不能保障每隔N秒執行一次,所以這時候我們需要用setTimeout模擬setInterval來保障確定的函數間隔時間。
setTimeout模擬setInterval,也可理解爲鏈式的setTimeout。
用法:
setTimeout(function () {
// 任務
setTimeout(arguments.callee, interval);
}, interval)