2013-03-13 25 views
2

在做$(element).on('customevent',function(){});,每一個綁定customevent也會觸發元素。這大致作爲Pub/Sub工作,看起來沒有順序或優先級。我想要做的是,實現我自己的回調隊列,但是,以一個可調整的優先級(比如WordPress的有,你可以設置鉤子的優先級)。所以更高的數字具有更大的優先級,並且數字0將是常用的並且最後執行。如何使用jQuery創建回調優先級隊列?

給出的例子$(element).on_priority(10, 'customevent', function(){});$(element).on_priority(0, 'customevent', function(){});,該10將優先執行相同customevent第一,並且可能還是不取消0優先級事件的執行。

我如何能實現呢?我有麻煩試圖以可視化的回調

到目前爲止,我認爲這樣的流程:

  • 保持一個「全球性」(我的瓶蓋內)的對象設置的所有回調的名稱。
  • 回調的每個成員的內部,包含所有優先級的對象。
var callbacks = { 
    'customevent': {}, 
    'customevent2': { 
    0: [{element: $element, fn: function(), data:{}}, {element: $element, fn: function(), data:{}}], 
    10: [{element: $element, fn: function(), data:{}}], 
    20: [{element: $element, fn: function(), data:{}}] 
    } 
}; 

是正確的方向?性能方面,它不應該是一個很大的衝擊,問題是反覆迭代對象。這裏的問題是,我將無法註銷先前設定的事件或設置的順序(或甚至重新排序)回調陣列每個優先

回答

4

我只是建議回調對象的數組裏面,你可以封裝在自己的對象中。該對象具有添加,刪除和執行的方法。添加,以優先順序添加給定的回調。刪除找到回調並將其刪除。執行調用優先順序每次回調,但回調停止進一步執行如有回調返回false

遍歷優先順序的回調很簡單,因爲回調保持在陣列中的排序順序(您剛剛從開始到結束的數組去)。

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

sortedCallbacks.prototype = { 
    // add callback to the list 
    add: function(fn, priority, data) { 
     var list = this.list; 
     var callbackObj = {fn: fn, priority: priority, data: data}; 

     for (var i = 0; i < list.length; i++) { 
      // if our new priority is greater, then insert it here 
      if (priority > list[i].priority) { 
       list.splice(i, 0, callbackObj); 
       return; 
      } 
     } 
     // if the list was either empty or no priorities in the list were less than 
     // the new priority, then just add this onto the end of the list 
     list.push(callbackObj); 
    }, 
    // remove callback from the list 
    remove: function(fn, priority) { 
     var list = this.list; 
     for (var i = 0; i < list.length; i++) { 
      if (list[i].fn === fn && list[i].priority === priority) { 
       list.splice(i, 1); 
       return; 
      } 
     } 
    }, 
    // change priority or data or both 
    change: function(fn, oldPriority, newPriority, data) { 
     this.remove(fn, oldPriority); 
     this.add(fn, newPriority, data); 
    } 
    // execute callbacks in order 
    execute: function(/* args for callback passed here */) { 
     // execute in priority order 
     var list = this.list, retVal, args; 
     for (var i = 0; i < list.length; i++) { 
      args = [].slice.call(arguments, 0); 
      // add the data for this callback to any arguments that were passed to execute 
      args.unshift(list[i].data); 
      retVal = list[i].fn.apply(this, args); 
      // if callback returns false, then stop further callback execution 
      if (retVal === false) { 
       return; 
      } 
     }   
    } 
}; 

使用範例:

// create callbacks object and add some callbacks to it 
var callbacks = new sortedCallbacks(); 
callbacks.add(fn1, 4, "whatever"); 
callbacks.add(fn2, 9, "hello"); 
callbacks.add(fn8, -1, "nothing"); 

// execute the callbacks and pass them each a value 
callbacks.execute(elem.value) 
+0

這是一個優秀的答案。我會試試這個並回到這個:) – pocesar 2013-03-13 09:21:13