JavaScript中定時器有兩種,一種是一次性定時器(setTimeout),另一種是週期性定時器(setInterval),兩種均可以延遲一段時間後再執行某個操做。不一樣的, setTimeout只執行一次,setInterval則一直執行,直到清除定時器爲止。ide
實際項目中,這兩種定時器都會用到,首先來講說setTimeout線程
1 setTimeoutcode
一次性定時器,執行一次後,自動取消,也能夠在延時以前,取消定時器隊列
function fun() { console.log("定時器") } setTimeout(fun, 1000);
延遲1秒後控制檯打印,定時器是以毫秒爲執行單位。也能夠用如下方式設置定時器事件
setTimeout(function () { console.log("定時器") }, 1000);
上面這種方式,若是要清除定時器,是不能清除的,只能在設置定時器的時候,定義一個變量來接收定時器的返回值,這樣才能夠清除定時器。ip
var timeFun = setTimeout(function () { console.log("定時器") }, 1000); clearTimeout(timeFun) 使用setTimeout模擬setInterval setTimeout(function () { // do something console.log("定時器") setTimeout(arguments.callee, 500) }, 500)
2 setIntervalget
週期性定時器,只要不主動清除定時器,就會一直執行消息隊列
function fun() { console.log("定時器") } setInterval(fun, 1000);
每隔一秒鐘,就會在控制檯打印一次。也能夠在setInterval裏面直接定義it
setInterval(function () { console.log("定時器") }, 1000);
一樣也是,若是要清除定時器,仍是須要定義一個變量來接收定時器的返回值。io
var timeFun = setInterval(function () { console.log("定時器") }, 1000); clearInterval(timeFun)
那咱們就說下setInterval的缺點,就是定時器指定的時間間隔,表示的是什麼時候將定時器推送到消息隊列,而不是什麼時候執行代碼。因此真正什麼時候執行定時器的時間是不能保證的,取決於什麼時候被主線程的事件循環取到並執行。那咱們若是要用定時器實現倒數、計時功能,如何避免定時器不許的問題。這裏就須要咱們使用setTimeout代替setInterval
var startTime = new Date().getTime() var count = 0; setInterval(function () { var i = 0; while (i++ < 100000000); }, 0); function fixed() { count++; var offset = new Date().getTime() - (startTime + count * 1000); var nextTime = 1000 - offset; if (nextTime < 0) nextTime = 0; setTimeout(fixed, nextTime); console.log(new Date().getTime() - (startTime + count * 1000)); } setTimeout(fixed, 1000);
上面方法,經過修正時間來延遲觸發,因此就保證了定時器的精準性。