【问题标题】:How to create a callback priority queue with the help of jQuery?如何借助 jQuery 创建回调优先级队列?
【发布时间】:2013-02-28 22:45:19
【问题描述】:

在执行$(element).on('customevent',function(){}); 时,每个绑定customevent 的元素也会触发。这大致作为 Pub/Sub 工作,似乎没有顺序或优先级。我想要做的是,实现我自己的回调队列,但是,具有可调整的优先级(就像 Wordpress 一样,您可以设置挂钩优先级)。因此,数字越大优先级越高,数字 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:{}}]
  }
};

方向对吗?就性能而言,它不应该受到太大影响,问题在于一遍又一遍地迭代对象。这样做的问题是我无法取消注册先前设置的事件或设置每个优先级内的回调数组的顺序(甚至重新排序)

【问题讨论】:

    标签: javascript jquery callback queue priority-queue


    【解决方案1】:

    我只是建议一个回调对象数组,您可以将它们封装在它自己的对象中。该对象具有添加、删除和执行的方法。添加,按优先级顺序添加给定的回调。 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)
    

    【讨论】:

    • 这是一个出色的答案。我会试试这个并回到这个:)
    猜你喜欢
    • 2012-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    • 2021-01-07
    • 2011-03-20
    相关资源
    最近更新 更多