首頁  >  文章  >  web前端  >  JavaScript循環失控的解決

JavaScript循環失控的解決

黄舟
黄舟原創
2016-12-15 10:49:081329瀏覽

javascript為網頁在客戶端帶來方便控制之外.也帶來了很多問題.其中腳本失控就是最頭痛的問題之一.

而使腳本失控的主要原因之一就是循環中執行了太多的操作

循環導致失控的原因有二條,一是循環休操作過多,二是循環次數過多.

解決這個問題的訣竅就是用下面這兩個問題來評估每個循環:

這個循環必須要同步執行麼? 
循環裡面的數據,必須依序執行麼? 
如果兩個問題的答案都是否定的話,你就可以選擇將循環裡的操作來分解。關鍵是要根據程式碼的具體環境來確定上面兩個問題的答案。典型的循環可能像下面這個樣子:

for(var i=0; i    process(items[i]);
}

乍一看這個循環並沒有太大的問題,是不是會運行很久完全取決於循環的次數。如果緊接循環後沒有其他程式碼在執行的時候需要依賴循環的結果,那麼第一個問題的答案就是「不」。你也可以發現,循環每次只處理一個數值,而且不依賴上一次循環的結果,所以第二個問題的答案同樣也是否定的。這就意味著,循環可以透過某種方式拆解,不會導致鎖定瀏覽器而顯示腳本失控的提示。

在《Professional JavaScript, Second Edition》這本書中,對於那些執行次數非常巨大的虛幻,我推薦使用下面的方式來處理:

function chunk(array, process, context){ 
function chunk(array, process, context){ 
function chunk(array, process, context){  setTimeout(function(Timeout(function(Timeout)(function( ){
       var item = array.shift();

       process.call(context,item);


 setTimeout(arguments.callee, 100);
       }
   }, 100) ;
}

chunk()函數的用途就是將一個陣列分成小塊處理(這也是名字的由來),我們可以傳遞三個參數。要處理的數組物件、處理函數以及一個可選的上下文變量,用於設定process()函數中對應的this物件。第一個timer用於處理操作之間的延遲(這裡設定為100毫秒,大家可以依照實際需要自行修改)。每次執行這個函數,都會將數組中的第一個對象取出,並傳給process()函數進行操作,如果這時process()中還有未處理完的對象,另外一個timer就會啟動,用於重複等待。上面提到的循環,可以透過下面的方法使用這個函數:

chunk(items, process);

需要注意的是,在這裡數組採用了隊列(queue)的形式,而且在循環的過程中,每次都會發生修改。如果你要修改陣列的原始狀態,這裡介紹兩種途徑:一種是透過concat()函數,在傳遞之前,建立一個目前陣列的副本:

chunk(items.concat(), process);

另一個選擇是直接修改chunk()函數,直接在函數內部進行修改:

function chunk(array, process, context){
   var items = array.concat();   //clone the array
 (){
       var item = items.shift();
       process.call(context, item);

 setTimeout(arguments.callee, 100);
       }
   }, 100 );
}

注意這種方法要比只保存一個索引安全的多,因為數組的內容在下次計時器生效之前可能會發生變化。

這裡提到的chunk()函數,只是最佳化循環效能的一個起點。你可以根據需要不斷改進它,讓它擁有更多的功能。比如說,在數組中所有物件都處理完成以後,可以增加一個函數回呼。無論你是否會以這種方式對函數進行修改,這只是一種JavaScript的程式碼開發模式,可以幫助優化陣列的處理效能,還可以避免那個腳本失控的警告。

以上就是JavaScript循環失控的解決的內容,更多相關文章請關注PHP中文網(www.php.cn)!


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn