例如,我有两个并发的AJAX请求,我需要这两个请求的结果来计算第三个结果。我使用的是Prototype库,所以它可能看起来像这样:
var r1 = new Ajax.Request(url1, ...);
var r2 = new Ajax.Request(url2, ...);
function on_both_requests_complete(resp1, resp2) {
...
}一种方法是使用轮询,但我认为肯定有更好的方法。
更新:可接受的解决方案必须没有竞争条件。
发布于 2010-03-16 04:25:02
在每个请求的回调函数上,设置一个布尔值,例如
request1Complete和request2Complete
然后打电话给on_both_requests_complete(resp1,resp2)。
在处理函数中,检查是否设置了两个布尔值。如果不是,就返回并退出函数。回调函数应该是序列化的,因为它们不能同时发生,所以这应该是可行的。如果它们可以并行发生,您将在竞争条件下中断。
发布于 2010-03-16 05:26:10
这就是我要做的。该方法是一种通用方法,它为您提供了更多的灵活性和重用性,并避免了耦合和全局变量的使用。
var makeEventHandler = function(eventMinimum, callback) {
var data = [];
var eventCount = 0;
var eventIndex = -1;
return function() {
// Create a local copy to avoid issues with closure in the inner-most function
var ei = ++eventIndex;
return function() {
// Convert arguments into an array
data[ei] = Array.prototype.slice.call(arguments);
// If the minimum event count has not be reached, return
if ( ++eventCount < eventMinimum ) {
return;
}
// The minimum event count has been reached, execute the original callback
callback(data);
};
};
};常规用法:
// Make a multiple event handler that will wait for 3 events
var multipleEventHandler = makeMultipleEventHandler(3, function(data) {
// This is the callback that gets called after the third event
console.log(data);
});
multipleEventHandler()(1,2,3);
var t = multipleEventHandler();
setTimeout(function() {t("some string");}, 1000);
multipleEventHandler()({a: 4, b: 5, c: 6});回调的输出(由Firebug压缩):
[[1, 2, 3], ["some string"], [Object { a=4, more...}]]请注意,在最后一个回调中,事件的顺序与调用事件的顺序相同,即使第二个“data”在第三个事件之后执行。
要在Ajax请求的上下文中使用它:
var onBothComplete = makeMultipleEventHandler(2, function(data) {
// Do something
...
});
new Ajax.Request(url1, {onComplete: onBothComplete()});
new Ajax.Request(url2, {onComplete: onBothComplete()});编辑:我更新了函数,强制data始终以同步执行的顺序维护异步接收的事件数据(前面的警告不再存在)。
发布于 2010-03-16 04:25:42
您必须记住,浏览器中的JS实现并不是真正的并发,并利用这一点对您有利。因此,您要做的是在每个处理程序中检查其他处理程序是否已完成。jQuery中的示例:
var other_done = false;
$.get('/one', function() {
if (other_done) both_completed();
other_done = true;
alert('One!');
});
$.get('/two', function() {
if (other_done) both_completed();
other_done = true;
alert('Two!');
});
function both_completed() {
alert('Both!');
}https://stackoverflow.com/questions/2450179
复制相似问题