开发者

How to implement the queue of events?

开发者 https://www.devze.com 2023-04-08 19:08 出处:网络
I need to implement the queue of events (=updates on the server). New events will be added to this queue when user changes the slider, presses buttons 开发者_如何学JAVAetc. Each event will contain the

I need to implement the queue of events (=updates on the server). New events will be added to this queue when user changes the slider, presses buttons 开发者_如何学JAVAetc. Each event will contain the following properties:

  1. device id (the action will be applied to that device on the server)
  2. action (set, get etc.)
  3. value (the value, which should be used in the action)

New event should be added there at the end. But in case there is already event for the same device id and with the same action, then this event should be updated with new value. How should I do that?

I've drafted the following:

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);

I use jquery mobile, probably it can help me to simplify such queue creation?


If you expect a short event queue, then the solution of @Martin is appropriate. The time complexity of his solution is O(n), where n is the queue length, and this is perfect if n is small.

If your queue could get long, then you might consider a faster approach like the following. The queue is represented by a map mapping the unique identifiers (device_id, action) to values. This provides a fast lookup of existing properties. The time complexity is reduced to O(log n). A convenient implementation of a map in Javascript is to use object properties that encode (device_id, action) into a unique string, e.g. "device_id#action". In addition, the properties are linked to provide first-in/first-out behavior.

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};  
    }   
};

The Map is used as follows:

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);             
    } 
} 


First of, you should only have one array holding an event object, otherwise you are really over complicating it for yourself.

next just loop over the events and see if one of the same device/action already exists when a new event is added.

try to do it something like this:

var inCall = false;
var queue = [];

// add call to the queue, at the end
function addAPICall(device, action, value){
  var found=false;
  for(var i=0, event; event = queue[i]; i++) {
    if(event.action == action && event.device == device) {
      event.value = value;
      found = true;
      break;
    }
  }
  if(!found) {
    queue.push({device: device, action: action, value: 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){
    var event = queue.shift();
        doAPICall(event.device, event.action, event.value);        
    }
}

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

精彩评论

暂无评论...
验证码 换一张
取 消