How To Set Callback Order Invocation Same As Target Function Invocation
I have a problem in my project. To describe this issue I have wrote simplified code snippet: function waitFor(fnReady, fnCallback) { var check = function() { if (fnRea
Solution 1:
Try this pattern
var map = "abcdefghi".split("");
var responses = []; // collect responses
$.ajaxSetup({
beforeSend : function(jqxhr, settings) {
jqxhr.id = Number(settings.data.split(/id=/)[1]); // add `id` to `request`console.log(settings.data.split(/id=/)[1]);
}
});
var request = function(id, data) {
// append `id` to `id` datareturn $.post("/echo/json/", {json:JSON.stringify([data]), id:id})
};
$.each(map, function(k, v) {
setTimeout(function() {
request(k + 1, v)
.done(function(data) {
// do stuff at each responseconsole.log(data); // note return values
})
.always(function(data, textStatus, jqxhr) {
// do stuff at each response
responses.push([jqxhr.id, data[0]]);
// do stuff when all requests completed , results items in `responses`if (responses.length === map.length) {
responses.sort(); // sort `responses` based on `id`// do stuff with `responses`console.log(responses);
}
});
},1 + Math.random() * 1000) // async
});
Solution 2:
my variant:
var index = 0;
// callback functionfunctiontryMe (param1) {
waitFor(function(){return param1 == index},
function(){console.log(param1);
index++;
}
)
}
// callback executer functioncallbackTester (callback,i) {
setTimeout( function(){callback(i);}, 20000 - i*1000);
}
// test functionfor(var i=0 ; i<10 ; i++){
callbackTester ( tryMe,i );
}
functionwaitFor(fnReady, fnCallback) {
var check = function() {
if (fnReady()) {
fnCallback();
}
else {
setTimeout(check, 100); // wait another 100ms, and try again
}
};
check();
}
Solution 3:
I personally would use promises for this, but you've said no promises (not sure why), so here's a generic sequencer algorithm in plain javascript (tested in the jsFiddle linked below):
functionsequence(fn) {
// initialize sequence data upon first useif (typeof sequence.low === "undefined") {
sequence.low = sequence.high = 0;
sequence.results = {};
}
// save id in local variable so we can reference it in the closure from the function belowvar id = sequence.high;
// advance to next sequence number
++sequence.high;
// initialize the result value for this sequence callback
sequence.results[id] = {fn: fn, args: [], ready: false, context: null};
returnfunction(/* args */) {
// save args and context and mark it readyvar args = Array.prototype.slice.call(arguments, 0);
// get the results object for this callback and save info in itvar thisResult = sequence.results[id];
thisResult.args = args;
thisResult.context = this;
thisResult.ready = true;
// now process any requests in order that are readyfor (var i = sequence.low; i < sequence.high; i++) {
var result = sequence.results[i];
// if this one is ready, process itif (result.ready) {
// increment counter past this result
++sequence.low;
// remove this stored resultdelete sequence.results[i];
// process this result
result.fn.apply(result.context, result.args);
} else {
// if this one not ready, then nothing to do yetbreak;
}
}
};
}
// your usage:
google.maps.event.addListener(searchBox, 'bounds_changed', sequence(renderTerminalsOnMapAndFitBounds));
...
$.getJSON('getAllTerminals.json', sequence(renderTerminalsOnMapAndFitBounds));
.....
$.getJSON('getAllTerminalsInsideRectangle.json', sequence(renderTerminalsOnMapAndFitBounds));
...
$.getJSON('getAllTerminalsInsideCircle.json', sequence(renderTerminalsOnMapAndFitBounds));
...
$.getJSON('getBigTerminals.json', sequence(renderTerminalsOnMapAndFitBounds));
........
Working demo: http://jsfiddle.net/jfriend00/aqugm1fs/
Conceptually, what this does is as follows:
- Pass a substitute completion handler in place of the normal completion callback.
- This substitute function marks each response with a sequence id and saved the original completion handler.
- If a response comes back while another response with a lower sequence id is still pending, then the result is just stored and saved for later.
- As each response comes in, it processes as many responses in sequence as are ready
Note: while all the examples you have use the same callback function, this will work with any callback function so it would work with a mix of different types of operations.
Post a Comment for "How To Set Callback Order Invocation Same As Target Function Invocation"