javascript - 如何实现事件队列?

标签 javascript jquery-mobile queue

我需要实现事件队列(=服务器上的更新)。当用户更改 slider 、按下按钮等时,新事件将添加到此队列中。每个事件将包含以下属性:

  1. 设备 ID(操作将应用于服务器上的该设备)
  2. 操作(设置、获取等)
  3. 值(应在操作中使用的值)

新事件应该添加到最后。但如果已经存在针对相同设备 ID 且具有相同操作的事件,则应使用新值更新该事件。我该怎么做?

我起草了以下内容:

var inCall = false;
var queueArrayDevices = new Array();
var queueArrayActions = new Array();
var queueArrayValues = new Array();

// add call to the queue, at the end
function addAPICall(device, action, value){
    // should NOT add event here, if device and action already exists
    // should update the value instead
    queueArrayDevices.push(device);
    queueArrayAсtions.push(action);
    queueArrayValues.push(value);
}

function doAPICall(device, action, value){    
    inCall = true;
    // call server here
    // if not successful, we should add this item to the queue again
    inCall = false;
}

function callAPIQueue(){
    if(!inCall && queueArrayDevices.length > 0){
        device = queueArrayDevices.shift();
        action = queueArrayAсtions.shift();
        value = queueArrayValues.shift();
        doAPICall(device, action, value);        
    }
}

// start queue processing
setInterval(callAPIQueue, 400);

我使用jquery mobile,也许它可以帮助我简化这样的队列创建?

最佳答案

如果您期望事件队列较短,那么@Martin 的解决方案是合适的。他的解决方案的时间复杂度是 O(n),其中 n 是队列长度,如果 n 很小时,这是完美的。

如果您的队列可能会很长,那么您可能会考虑采用如下更快的方法。队列由将唯一标识符(device_id、action)映射到值的映射来表示。这提供了对现有属性的快速查找。时间复杂度降低到O(log n)。 Javascript 中 map 的一种便捷实现是使用将 (device_id, action) 编码为唯一字符串的对象属性,例如“device_id#action”。此外,这些属性相互链接以提供先进/先出行为。

var Map = {
    // properties: "id#action": {value: value, next: property}
    first: "",
    last: "",
    empty: function() {return Map.first == "";},
    enque: function(device, action, value) {
        var k = device + "#" + action;
        if (k in Map) {
            Map[k].value = value;
        }
        else {
            Map[k] = {value: value, next: ""};
            if (Map.first == "") {
                Map.first = Map.last = k;
            }
            else {
                Map[Map.last].next = k;
                Map.last = k;
            }               
        }

    },
    deque: function() {
        var firstProp = Map.first;
        var key = firstProp.split("#");
        var value = Map[firstProp].value;
        Map.first = Map[firstProp].next;
        delete firstProp; // delete this property
        return {device: key[0], action: key[1], value: value};  
    }   
};

map 的使用方式如下:

function addAPICall(device, action, value) {
    Map.enque(device, action, value);
}    
function callAPIQueue() {     
    if (!inCall && !Map.empty()) {     
        var event = Map.deque();         
        doAPICall(event.device, event.action, event.value);             
    } 
} 

关于javascript - 如何实现事件队列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7544720/

相关文章:

javascript - jQuery:如果 dom 元素不存在,则添加它

javascript - 整个页面的玻璃面板

javascript - 如何克隆具有值的行

jquery - 一起使用 jquery 和 jquery.mobile 时 CSS 不起作用

javascript - i18next 翻译问题

c - 使用循环链表实现Queue

javascript - 不使用数组方法删除数组中的第一个元素

Apache webserver - 当所有工作线程都忙时,请求会发生什么

javascript - 为 javascript 测试创建 HTML 元素

css - jQuery Mobile 中的谷歌地图