如何获取两个异步函数的两个参数?

时间:2011-10-11 05:41:29

标签: javascript asynchronous

var o = new X();
o.setFooCallback1(function(result1){
});
o.setFooCallback2(function(result2){
});
o.foo("xxx");  

正如您所看到的,当我致电o.foo()时,会有两个回调,其中包含两个结果,result1result2,我想要做的就是使用pass { {1}}和result1到我的构造函数来创建一个对象:

result2

但是result1和result2来自不同的时间(异步),我该如何处理呢? ps:类var y = new Y(result1, result2); 来自其他人的库,我无法修改它的实现

3 个答案:

答案 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)

基本上你需要添加另一个层,它在第一层的两个回调都执行后触发回调,可能在另一个对象中。答案非常好:

jQuery callback for multiple ajax calls

答案 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"); 

})();

请注意,我添加了一个闭包,以便yr1r2不会成为全局变量,但保持在任务的本地。

如果r1r2的值可以评估为false,那么请务必相应地更新if语句:)