如何设置与目标函数调用相同的回调顺序调用 [英] How to set callback order invocation same as target function invocation
问题描述
我的项目有问题.
为了描述这个问题,我编写了简化的代码段:
To describe this issue I have wrote simplified code snippet:
function waitFor(fnReady, fnCallback) {
var check = function() {
if (fnReady()) {
fnCallback();
}
else {
setTimeout(check, 100); // wait another 100ms, and try again
}
};
check();
}
var result = 0;
var flag = true;
function ajaxRequest() {
setTimeout(
function() { flag = false;
console.log('ping');
},3000
);
}
function ajaxRequestHandler() {
setTimeout(
function() { flag = true;
console.log('pong');
}, 200
);
}
for(var i =0;i<10; i++){
waitFor(function() { return flag; }, ajaxRequest);
waitFor(function() { return !flag; }, ajaxRequestHandler);
}
它返回:
ping - 10 times
pong - 10 times
所需结果:
ping
3 second timeout
ping
---------------------
ping
3 second timeout
pong
--------------------
.....
您能帮我更正我的代码吗?
Can you help correct my code?
实际问题:
我有一张Google地图.
我应该重绘很多地方.
I have a google map.
I have a lot of places when I should to redraw it.
对于应用程序逻辑,如果我发送
For application logic very important that If I send
request1
request2
request3
request4
我应该按此顺序处理回复
I should handle responses in the this order
handle response of request1
handle response of request2
handle response of request3
handle response of request4
我不知道请求顺序的问题.
Problem that I don't know order of requests.
在文件的不同位置,我看到以下代码行:
In different places of file I see following code rows:
google.maps.event.addListener(searchBox, 'bounds_changed', renderTerminalsOnMapAndFitBounds);
...
$.getJSON('getAllTerminals.json', renderTerminalsOnMapAndFitBounds);
.....
$.getJSON('getAllTerminalsInsideRectangle.json', renderTerminalsOnMapAndFitBounds);
...
$.getJSON('getAllTerminalsInsideCircle.json', renderTerminalsOnMapAndFitBounds);
...
$.getJSON('getBigTerminals.json', renderTerminalsOnMapAndFitBounds);
........
renderTerminalsOnMapAndFitBounds
方法将请求发送到服务器,并成功在地图上替换呈现结果.但是这个事件经常发生
renderTerminalsOnMapAndFitBounds
method sends request to server and in succes alternative render result on map. But this event happens very often
推荐答案
我个人会使用promise,但是您说的没有promise(不确定原因),因此这是普通javascript中的通用音序器算法(已在链接下面的jsFiddle):
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):
function sequence(fn) {
// initialize sequence data upon first use
if (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 below
var 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};
return function(/* args */) {
// save args and context and mark it ready
var args = Array.prototype.slice.call(arguments, 0);
// get the results object for this callback and save info in it
var thisResult = sequence.results[id];
thisResult.args = args;
thisResult.context = this;
thisResult.ready = true;
// now process any requests in order that are ready
for (var i = sequence.low; i < sequence.high; i++) {
var result = sequence.results[i];
// if this one is ready, process it
if (result.ready) {
// increment counter past this result
++sequence.low;
// remove this stored result
delete sequence.results[i];
// process this result
result.fn.apply(result.context, result.args);
} else {
// if this one not ready, then nothing to do yet
break;
}
}
};
}
// 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));
........
正在运行的演示: http://jsfiddle.net/jfriend00/aqugm1fs/
从概念上讲,其作用如下:
Conceptually, what this does is as follows:
- 传递一个替代完成处理程序代替正常的完成回调.
- 此替代函数使用序列ID标记每个响应,并保存了原始的完成处理程序.
- 如果一个响应返回时,另一个序列号较低的响应仍在等待处理,则结果将被存储并保存以备后用.
- 每个响应进入时,它会按顺序处理尽可能多的响应
注意:虽然所有示例都使用相同的回调函数,但该函数可与任何回调函数一起使用,因此可以混合使用不同类型的操作.
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.
这篇关于如何设置与目标函数调用相同的回调顺序调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!