2012-07-07 36 views
3

比方說,有一組Watcher s表示需要定期刷新。它們每個可能有不同的刷新間隔。在任何給定時刻可能有幾百個這樣的Watcher項目。任何Watcher的刷新時間可以從一秒到幾分鐘或幾小時。它是更有效地使用一束一個定時器的或setInterval的刷新一堆對象

哪個更好?

  • 爲每一個使用單獨的setTimeout

  • 使用運行功能每秒一setInterval。然後函數循環檢查每個Watcher是否需要刷新。

起初我認爲的setTimeout的本機代碼實現會比不檢查JS功能更有效,但它是真正的如何setTimeout實現一個問題,每超時多少開銷花費在每基準,以及超時數量如何擴展。

我問這一個節點應用程序,我指的是具體的引擎V8,但如果有人知道其他引擎的詳細信息以及它會是很酷的。

回答

3

這裏有一個想法,應該是相當有效的,無論的setTimeout或setInterval的是如何實現的。如果將來有N個事件安排在N個不同時間,請創建一個對象數組,其中每個對象都有一個事件到期時間的屬性,以及一個屬性,告訴您它是什麼類型的事件(回調或某些事件其他標識符)。最初通過time屬性對數組進行排序,以便下一次處於事件的前端,最遠的時間處於末尾。

然後,查找在陣列的前部,計算值的時間,直到該事件並在該持續時間做setTimeout()。當setTimeout()激發時,查看數組的開始並處理已到達時間的所有事件。如果在處理完一個事件之後,你需要安排下一次事件,在將來應該觸發時計算時間,並從頭到尾遍歷數組,直到找到事件之後並在該事件之前插入該事件(保持數組按排序順序)。如果沒有找到,請將其插入最後。在處理完時間到達的陣列前面的所有事件後,計算Delta時間到陣列前端的事件,併爲該時間間隔發出新的setTimeout()

下面是一些僞代碼:

function orderedQueue() { 
    this.list = []; 
} 

orderedQueue.prototype = { 
    add: function(time, callback) { 
     var item = {}, added = false; 
     item.time = time; 
     item.cb = callback; 
     for (var i = this.list.length - 1; i >= 0; i--) { 
      if (time > this.list[i].time) { 
       // insert after the i item 
       this.list.splice(i + 1, 0, item); 
       added = true; 
       break; 
      } 
     } 
     // if no item was after this item, 
     // then put this on the front of the array 
     if (!added) { 
      this.list.unshift(item); 
     } 
    }, 
    addDelta(delta, callback) { 
     var now = new Date().getTime(); 
     this.add(now + delta, callback); 
    }, 
    waitNext: function() { 
     // assumes this.list is properly sorted by time 
     var now = new Date().getTime(); 
     var self = this; 
     if (this.list.length > 0) { 
      // set a timer for the first item in the list 
      setTimeout(function() { 
       self.process(); 
      }, this.list[0].time - now); 
     } 
    }, 
    process: function() { 
     var now,item; 
     // call all callbacks who's time has been reached 
     while (this.list.length) { 
      now = new Date().getTime(); 
      if (this.list[0].time <= now) { 
       // remove front item from the list 
       item = this.list.shift(); 
       // call the callback and pass it the queue 
       item.cb(this); 
      } else { 
       break; 
      } 
     } 
     // schedule the next item 
     this.waitNext(); 
    } 
} 

而且,這裏通常是你將如何使用它:

var q = new orderedQueue(); 
// put initial events in the queue 
q.addDelta(100, f1); 
q.addDelta(1000, f2); 
q.addDelta(5000, f3); 
q.addDelta(10000, f4); 
q.addDelta(200, f5); 
q.addDelta(100, f1); 
q.addDelta(500, f1); 
// start processing of queue events 
q.waitNext(); 
+0

絕對可以工作。現在我必須弄清楚JS中是否有一種好方法來使用鏈表。 – download 2012-07-07 17:54:01

+0

@download - 我添加了一個只使用排序數組的可能實現。 – jfriend00 2012-07-07 18:10:54

+0

好吧,沒有人回答這個問題,但是你的建議很有用,所以我會將它標記給你。 – download 2012-07-10 22:52:48

相關問題