2013-09-30 46 views
3

我有這段代碼使用on()從Firebase獲取數據,on()我創建對象,我想發送函數以供將來使用 - 使用return,但它似乎沒有任何回報。 所以問題是我該怎麼做纔對?Firebase on()不返回任何東西

postsRef.on('value', function(snapshot) { 
if (snapshot.val() === null) { 
var allPosts = false, 
numberOfPosts = 0; 
} 
else { 
    var allPosts = snapshot.val(), 
    numberOfPosts = Object.size(allPosts); 
} 
var postsData = { 
    content: allPosts, 
    count: numberOfPosts 
}; 
return postsData; 
}); 

回答

6

回調函數被異步調用(將來有一段時間)。所以在它被調用的時候,postsRef.on(...)已經返回並且它的任何代碼都會立即運行。

例如,這可能是誘人的,但不會工作:

var postsData; 
postsRef.on('value', function(snapshot) { 
    postsData = snapshot.val(); 
}); 
console.log(postsData); // postsData hasn't been set yet! 

因此,有解決這幾個不同的方式。最好的答案將取決於偏好和代碼結構:

移動訪問postsData邏輯步入回調

postsRef.on('value', function(snapshot) { 
    postsData = snapshot.val(); 
    console.log(postsData); 
}); 

調用回調時被調用另一個函數

function logResults(postsData) { 
    console.log(postsData); 
} 

postsRef.on('value', function(snapshot) { 
    logResults(snapshot.val()); 
}); 

觸發事件

function Observable() { 
    this.listeners = []; 
} 

Observable.prototype = { 
    monitorValue: function(postsRef) { 
     var self = this; 
     postsRef.on('value', function(snapshot) { 
     self._notifyListeners(postsRef); 
     }); 
    }, 

    listen: function(callback) { 
     this.listeners.push(callback); 
    }, 

    _notifyListeners: function(data) { 
     this.listeners.forEach(function(cb) { 
     cb(data); 
     } 
    } 
}; 

function logEvent(data) { 
    console.log(data); 
} 

var observable = new Observable(); 
observable.listen(logEvent); 
observable.monitorValue(/* postsRef goes here */); 
+0

謝謝你的回答,我還是有點困惑。當我在回調中移動邏輯時,會觸發很多次 - 在ref的每次更改期間,我都會使用once()。對我來說最好的方式是將數據從返回的對象中取出,也許類似於這裏提到的:使用promise()函數http://stackoverflow.com/questions/11636731/handling-asynchronous-calls-firebase-in-functions在jQuery中,但是無論如何都要感謝:) – Johncze

+1

如果你現在只想獲得數據值的通知,並且在將來它不會改變,那麼once()就是要走的路!在異步世界中不存在「返回對象」這樣的事情,因爲沒有辦法知道實際上何時會調用相對於後面代碼的回調。如果他們對你更有意義,承諾也是一個很好的選擇。 – Kato