setTimeout()和setInterval()可以用來建立定時器,其基本的用法這裡就不再做介紹了。這裡主要介紹一下javascript的程式碼佇列。在javascript中沒有任何程式碼是立即執行的,一旦進程空閒就盡快執行。所以說定時器中設定的時間不代表執行時間就一定相符,而是代表代碼會在指定時間間隔後加入佇列等待。如果在這個時間點上,佇列中沒有其他東西,那麼這段程式碼就會被執行,表面上看起來好像程式碼就在精確指定的時間點上執行了。所以就會產生一些問題。
重複定時器
通常,我們使用setInterval方法來以相同時間間隔重複執行某段程式碼。但是使用該方法會有兩個問題:第一個是某些間隔會被跳過;第二個就是多個定時器的程式碼執行之間的間隔可能會比預期的小。
在這裡,我們來舉個例子:如果某個onclick事件處理程序使用setInterval設定了一個200ms間隔的重複定時器,如果事件處理程序花了300ms的時間完成,就會跳過一個時間間隔同時運行一個定時器代碼。
我們也可以透過下面的程式碼來得到結論:
//重复定时器 var i =0; setInterval(function(){ //如果事件处理时间长于间隔时间 i++; for(var j=0;j<100000000;j++){} document.write(i+' '); },100); //可以明显感觉到时间间隔不相等 为了避免这种时间间隔的问题,我们可以采用链式调用setTimeout方法来取代setInterval。 //可以采用链式调用setTimeout来取代setInterval var i = 0; setTimeout(function(){ //处理内容 i++; for(var j=0;j<100000000;j++){} document.write(i+' '); // setTimeout(arguments.callee,100); },100); //这样处理效果明显好多了。
每次函數執行的時候都會建立一個新的計時器,第二個setTimeout呼叫使用了arguments.callee來取得目前執行的函數的引用,並為其設定另一個計時器。這樣做是為了在前一個定時器代碼執行完之前,不會向隊列插入新的定時器代碼,確保不會有任何缺失的間隔,也保證了在下一次定時器代碼執行之前,至少要等待指定的間隔,避免了連續的運轉。可謂一舉兩得,現在主流框架中的動畫一般都是這樣來實現重複定時的。
函數節流
定時器不只是用來定時的,也可以用來緩解瀏覽器的壓力。瀏覽器中某些計算和處理要比其他的昂貴很多,比如說DOM操作,就會需要更多的記憶體和CPU時間,連續使用過多的DOM操作可能會導致瀏覽器掛起,甚至崩潰。
函數節流的基本想法就是,某些程式碼不可以在沒有間斷的情況連續重複執行。第一次呼叫函數,建立一個定時器,在指定的時間間隔之後執行程式碼。當第二次呼叫函數時,它會清除前一次的計時器並設定一個。目的就是為了在執行函數的請求停止一段時間後再執行。
程式碼如下:
//再来谈谈函数节流 function throttle(method,context){ clearTimeout(method.tId); method.tId = setTimeout(function(){ method.call(context); },100); } //该函数接受两个参数,第一个是要执行的函数,第二个是作用域。 //使用方法demo //未使用情况: window.onresize = function(){ var div = document.getElementByTagName(body); div.style.height = div.offsetWidth +'px'; } //使用情况; function resizeDiv(){ var div = document.getElementByTagName(body); div.style.height = div.offsetWidth +'px'; } window.onresize = function(){ throttle(resizeDiv); }; //只要代码是周期性执行的,都应该使用节流。
這樣給使用者的感覺並不會很大,確是給瀏覽器減少了不少的壓力,函數節流也是許多框架常用的技巧之一。
以上就是關於javascript高階定時器的相關介紹,希望對大家的學習有所幫助。