2011-10-11 47 views
1
var o = new X(); 
o.setFooCallback1(function(result1){ 
}); 
o.setFooCallback2(function(result2){ 
}); 
o.foo("xxx"); 

,你可以看到,當我打電話o.foo(),這裏有兩種回調將有兩個結果,result1result2,我想做的事被解僱在使用通result1result2我的構造函數來創建一個對象:如何獲取兩個異步函數的兩個參數?

var y = new Y(result1, result2); 

但result1和result2進來不同的時間(異步),我該如何處理?
PS:類X是從別人的圖書館,我不能修改它的FPGA實現

回答

3

您需要實現所謂的semaphore pattern

這裏是一個手-on實現:

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()) 

請注意,它只捕獲第一個回調參數,但您可以輕鬆地將其擴展爲任何您需要的。

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,r1r2不會成爲全局變量,但保持本地任務。

如果任r1r2可以計算結果爲假值,然後確保更新if語句相應:)