当执行 $(element).on('customevent',function(){});
时,绑定(bind) customevent
的每个元素也会触发。这大致作为 Pub/Sub 工作,并且似乎没有顺序或优先级。我想做的是,实现我自己的回调队列,但是,具有可调整的优先级(就像 Wordpress 一样,您可以设置 Hook 优先级)。所以数字越大优先级越高,数字 0 将是一个普通的并最后执行。
给定示例 $(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:{}}]
}
};
方向对吗?在性能方面它不应该受到太大影响,问题在于一遍又一遍地迭代对象。这样做的问题是我无法注销先前设置的事件或设置顺序(甚至重新排序)每个优先级内的回调数组
最佳答案
我只是建议一个回调对象数组,您可以将它们封装在自己的对象中。该对象具有添加、删除和执行的方法。添加,按优先顺序添加给定的回调。 Remove 找到回调并将其删除。 Execute 按优先顺序调用每个回调,但如果任何回调返回 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)
关于javascript - 如何借助 jQuery 创建回调优先级队列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15377865/