js高級技巧之高級定時器


實際上,瀏覽器負責進行排序,指派某段代碼在某個時間點運行的優先級。

可以吧js想象成在時間線上運行的。

JavaScript中沒有任何代碼是立刻執行的,但一旦進程空閑則盡快執行。

1.重復的定時器:

setInterval()的重復定時器存在兩個缺點:

(1)某些間隔會被跳過

(2)多個定時器的代碼執行之間的間隔可能比預期的小;

假設,某個onclick事件處理程序使用setInterval()設置了一個200ms間隔的重復定時器。如果事件處理程序花了300ms多一點的時間完成,同時定時器代碼也花了差不多的時間,就會同時出現跳過間隔且連續運行定時器代碼的情況。

 為了避免這個缺點,可以使用鏈式setTimeout()調用。

 

		setTimeout(function() {
			setTimeout(arguments.callee, interval);
		},interval)

callee是arguments的一個屬性,指的是對函數對象本身的引用。

2.Yielding Processes

運行在瀏覽器中的JavaScript都被分配了一個確定數量的資源。

腳本長時間運行的問題通常是由兩個原因之一造成的:

(1)過長的、過深嵌套的函數調用。

(2)進行大量處理的循環。

		for (var i = 0,len=data.length; i < len; i++) {
			process(data[i]);
		};

process要花100ms,那么總的花費時間是由數組的長度決定的。JavaScript的執行是一個阻塞操作,腳本運行花費的時間越久,用戶無法與頁面交互的時間也越久。

 

解決這個問題有一種技術叫做:數組分塊

小塊小塊地處理數組,通常每次一小塊。

基本的思路是為要處理的項目創建一個小隊列,然后使用計時器取出下一個要處理的項目進行處理,接着再設置另一個定時器。

 1         function chunk(array, process, context) {
 2             setTimeout(function(){
 3                 var item = array.shift();
 4                 process.call(context, item);
 5 
 6                 if (array.length>0) {
 7                     setTimeout(arguments.callee, 100);
 8                 };
 9             }, 100)
10         };
11 
12         var data = [12,12,1234,453,436,23,23,5,4123,45,346,3563,2234,345,342];
13 
14         function printValue(item) {
15             var div = document.getElementById('myDiv');
16             div.innerHTML += item + "</br>";
17         };
18         chunk(data.concat(), printValue);

chunk方法接收三個參數:要處理的項目的數組,用於處理項目的函數,運行該函數的環境。這個函數用來處理數組。

調用chunk時,為了不改變數組原來的值,用到了一個concat方法:(返回一個新的數組,此方法里面可以添加參數。這些參數和調用的數組組成一個新的數組。)。由於printValue函數處在全局作用域內,因此無需給chunk()傳遞一個context對象。

 

3.函數節流:

函數節流的思想是:某些代碼不可以在沒有間斷的情況下連續重復執行。

第一次調用函數,創建一個定時器,在指定的時間間隔后運行代碼。當第二次調用該函數時,它會清除前一次的定時器並設置另一個。

		function printValue(item) {
			var div = document.getElementById('myDiv');
			div.innerHTML += item + "</br>";
		};
		chunk(data.concat(), printValue);

		// 函數節流
		function throttle(method, context) {
			clearTimeout(method.tId);
			method.tId = setTimeout(function(){
				method.call(context);
			}, 100)
		};

		function resizeDiv() {
			var div = document.getElementById('myDiv');
			div.style.height = div.offsetWidth + "px";
		};

		window.onresize = function() {
			throttle(resizeDiv);
		};

throtttle函數用來進行函數節流:這個函數首先清除之前設置的定時器。然后定義定時器,在100ms后再執行method方法(method.call(context)是為了確保方法在適當的環境中執行)。如果這個throttle在100ms內執行了50次,那么method方法也只會執行次。(這就是節流)

window.onresize方法會造成瀏覽器運行緩慢的兩個原因:

(1)首先,要計算offsetWidth屬性,如果該元素或者頁面上其他元素有非常復雜的css樣式,那么整個過程將會很復雜。

(2)其次,設置某個元素的高度需要對頁面進行回流來令改動生效。如果頁面有很多元素同時應用了相當數量的css的話,這個又需要很多的計算。

 

只要代碼是周期性執行的,都應該使用節流,但是你不能控制請求的執行的效率。可以改動throttle函數的時間間隔。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM