如何在JavaScript中處理大量數(shù)據(jù)
51CTO推薦專(zhuān)題:JavaScript學(xué)習(xí)筆記 有問(wèn)有答
在幾年之前,開(kāi)發(fā)人員不會(huì)去考慮在服務(wù)端之外處理大量的數(shù)據(jù)。現(xiàn)在這種觀念已經(jīng)改變了,很多Ajax程序需要在客戶(hù)端和服務(wù)器端傳輸大量的數(shù)據(jù)。此外,更新DOM節(jié)點(diǎn)的處理在瀏覽器端來(lái)看也是一個(gè)很耗時(shí)的工作。而且,需要對(duì)這些信息進(jìn)行分析處理的時(shí)候也很可能導(dǎo)致程序無(wú)響應(yīng),瀏覽器拋出錯(cuò)誤。
將需要大量處理數(shù)據(jù)的過(guò)程分割成很多小段,然后通過(guò)JavaScript的計(jì)時(shí)器來(lái)分別執(zhí)行,就可以防止瀏覽器假死。先看看怎么開(kāi)始:
- function ProcessArray(data,handler,callback){
ProcessArray()方法支持三個(gè)參數(shù):
◆data:需要處理的數(shù)據(jù)
◆handler:處理每條數(shù)據(jù)的函數(shù)
◆callback:回調(diào)函數(shù)
然后定義一些變量:
- var maxtime = 100;
- var delay = 20;
- var queue = data.concat();
maxtime表示每個(gè)處理進(jìn)程的最大毫秒數(shù)。delay表示每個(gè)程序塊之間的毫秒數(shù)。queue是源數(shù)據(jù)的復(fù)制,雖然不是在所有情景下都必要,但是我們是通過(guò)傳遞引用修改的,所以最好還是備份一下。
然后就可以使用setTimeout()方法來(lái)處理了:
- setTimeout(function(){
- var endtime = new Date() + maxtime;
- do{
- hanler(queue.shift());
- }while(queue.length>0 && endtime > new Date());
首先,先計(jì)算endtime,這是程序處理的最大時(shí)間。do.while 循環(huán)用來(lái)處理每一個(gè)小塊的數(shù)據(jù),直到循環(huán)全部完成或者超時(shí)。
為什么使用do..while循環(huán)呢?
JavaScript支持while和do…while循環(huán)。不同之處在于do..while循環(huán)回至少執(zhí)行一次。如果使用while循環(huán),那么當(dāng)開(kāi)發(fā)者設(shè)置一個(gè)很小或者很低的endtime值的時(shí)候,那么處理就根本不會(huì)執(zhí)行了。
最后,我們?cè)贈(zèng)Q定是否需要處理其他的數(shù)據(jù),如果需要,那么就再調(diào)用一次:
- if (queue.length > 0) {
- setTimeout(arguments.callee, delay);
- }
- else {
- if (callback) callback();
- }
- }, delay);
這樣回調(diào)函數(shù)會(huì)在每一個(gè)數(shù)據(jù)都處理結(jié)束的時(shí)候執(zhí)行。我們可以通過(guò)ProcessArray()來(lái)測(cè)試一小組數(shù)據(jù):
- // process an individual data item
- function Process(dataitem) {
- console.log(dataitem);
- }
- // processing is complete
- function Done() {
- console.log("Done");
- }
- // test data
- var data = [];
- for (var i = 0; i < 500; i++) data[i] = i;
- // process all items
- ProcessArray(data, Process, Done);
這個(gè)方法在任何瀏覽器中都可以執(zhí)行,不過(guò)HTML 5提供了更好的辦法,可參考專(zhuān)題:HTML 5 下一代Web開(kāi)發(fā)標(biāo)準(zhǔn)詳解
原文鏈接:http://rockux.com
【編輯推薦】