var o = new X();
o.setFooCallback1(function(result1){
});
o.setFooCallback2(function(result2){
});
o.foo("xxx");
正如您所看到的,当我致电o.foo()
时,会有两个回调,其中包含两个结果,result1
和result2
,我想要做的就是使用pass { {1}}和result1
到我的构造函数来创建一个对象:
result2
但是result1和result2来自不同的时间(异步),我该如何处理呢?
ps:类var y = new Y(result1, result2);
来自其他人的库,我无法修改它的实现
答案 0 :(得分:3)
您需要实现所谓的semaphore pattern
这是一个动手实施:
var o = new X()
, n = 0
, result1, result2
function checkResults(){
if (--n > 0) return;
var y = new Y(result1, result2)
}
o.setFooCallback1(function(res){
result1 = res
checkResults()
})
o.setFooCallback2(function(res){
result2 = res
checkResults()
})
或面向对象的方法:
function Semaphore(callback){
this.callback = callback
this.count = 0
this.args = []
}
Semaphore.prototype.check = function(){
if (--this.count <= 0)
this.callback.apply(null, this.args)
}
Semaphore.prototype.queue = function(){
var self = this
self.count++
return function(res){
self.args.push(res)
self.check()
}
}
var fooResults = new Semaphore(function(res1, res2){
var y = new Y(res1, res2)
})
o.setFooCallback1(fooResults.queue())
o.setFooCallback2(fooResults.queue())
请注意,它仅捕获第一个回调参数,但您可以轻松地将其扩展为您需要的任何内容。
答案 1 :(得分:1)
基本上你需要添加另一个层,它在第一层的两个回调都执行后触发回调,可能在另一个对象中。答案非常好:
答案 2 :(得分:0)
在两个回调中调用相同的函数,但只有在它们都返回后才实际执行任何操作,如下所示:
(function(){
var y, r1, r2;
function runWhenBothReturn() {
if(r1 && r2) { //check both are set to a non-falsy value
y = new Y(r1, r2);
}
}
var o = new X();
o.setFooCallback1(function(result1){
r1 = result1;
runWhenBothReturn();
});
o.setFooCallback2(function(result2){
r2 = result21;
runWhenBothReturn();
});
o.foo("xxx");
})();
请注意,我添加了一个闭包,以便y
,r1
和r2
不会成为全局变量,但保持在任务的本地。
如果r1
或r2
的值可以评估为false,那么请务必相应地更新if语句:)