2013-03-13 77 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