javascript - 如何借助 jQuery 创建回调优先级队列?

标签 javascript jquery callback queue priority-queue

当执行 $(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/

相关文章:

javascript - Web Scrape JS 渲染网站

javascript - AttachEvent 在 Chrome 浏览器中不适用于焦点事件

javascript - 如何使用带有#signature的javascript var来指向id?

javascript - 为什么 ajax 请求会多次触发

javascript - 删除多个 localStorage 项

c - 如何动态分配函数代码?

c++ - 在 C++ 中无效使用类?

javascript/node.js 从函数内部的函数回调数据

javascript - 使用 Javascript 格式化纯文本的最快方法

jquery - 使用jquery和 session 存储但系统崩溃