2015-02-07 54 views
1

我想創建一個帶有firebase的javascript的學生考勤跟蹤器應用程序。Firebase查詢裏面的函數返回null

但我有一個問題,我試圖查詢一個函數內部並讓函數返回這些數據。

但是,當我嘗試,它什麼都沒有返回。 '未定義'

這裏是我的代碼

var root = 'https://path.firebaseio.com'; 
function initFireSubjects(){ 
    var db = {}; 
    db.connection = new Firebase(root + '/subjects'); 
    db.addSubject = function (year, code, name) { 
     this.connection.child(year).push({ 
      code: code, 
      name: name 
     }); 
    }; 
    db.getAll = function (year) { 
     var value; 
     this.connection.child(year).on('value', function (snapshot) { 
      value = snapshot.val(); 
     }); 
     return value; 
    }; 
} 

,這裏是我的代碼來測試它

var db = initFireSubjects(); 
var test = db.getAll('2014'); 
console.log(test); 

數據的結構看起來像這樣

subject:{ 
    '2014':{ 
     randomKey1:{ 
      code:'eng1', 
      name:'English 1' 
     }, 
     randomKey2:{ 
      code:'math1', 
      name:'Mathematics 1' 
     }, 
     randomKey3:{ 
      code:'sci1', 
      name:'Science 1' 
     } 
    }, 
    '2015':{ 
     randomKey4:{ 
      code:'polsci1', 
      name:'Political Science 1' 
     }, 
     randomKey5:{ 
      code:'comprog', 
      name:'Computer Programming' 
     } 
    } 
} 

的情況下,是我可以拉數據,如果我這樣做的話

db.getAll = function(year){ 
    var value; 
    this.connection.child(year).on('value',function(snapshot){ 
     value = snapshot.val(); 
     console.log(value); 
    } 
} 

我不知道爲什麼它不能以面向對象的方式提取數據。

任何輸入?

謝謝。

回答

3

你所看到的與OO沒有多大關係,但是事實上Firebase是(與大多數現代網絡一樣)在本質上是異步的。

當你註冊使用火力地堡的on事件處理程序,火力地堡開始檢索並在該位置監控數據。由於檢索數據可能需要一些時間(並且更新的數據可能隨時到達),瀏覽器將繼續執行您的JavaScript。一旦數據可用,您的回調函數就會被調用。

這是比較容易看到,如果我們編寫代碼略有不同發生的事情一點:

/* 1 */ db.getAll = function (year) { 
/* 2 */  var value; 
/* 3 */  this.connection.child(year).on('value', db.onValue); 
/* 4 */  return value; 
/* 5 */ }; 
/* 6 */ db.onValue = function(snapshot) { 
/* 7 */  value = snapshot.val(); 
/* 8 */  console.log(value); 
/* 9 */ }); 

當你的getAll函數執行時,它首先聲明一個變量value。在3行中,它會告知Firebase,當它從服務器獲得一年的值時,請致電db.onValue。 Firebase會檢索該值,但您的JavaScript仍會繼續執行。因此,在第4行中,您將返回value,該行仍未初始化。所以你要退回undefined

某些時候,您要求的價值從Firebase的服務器返回。當發生這種情況時,將調用onValue函數,並在第8行輸出年份。

有一件事可能會幫助您接受爲什麼這很有用:如果另一個現在更新Firebase中的年份,則onValue函數將會再次調用。 Firebase不會只檢索一次數據,它會監控數據更改的位置。

異步加載不是Firebase特有的。幾乎所有在JavaScript中開始爲現代Web編程的人都會在某個時刻被這個問題困擾。你能做的最好的事情就是接受並接受異步性(即使是一個字?)快速處理它。

處理它通常意味着您將要使用新值執行的操作移到回調函數中。因此,我在第8行中添加的console.log也可以使用document.querySelector('#currentyear').textContent = value之類的內容更新您的UI。

也讀這個答案(它使用的是AngularFire,但問題是相同的):Asynchronous access to an array in Firebase和其他一些從那裏鏈接的問題。

+0

謝謝你回覆良好的先生。這是很好的信息。 – 2015-02-07 14:14:00

+0

不客氣。如果答案有用,請按下向上箭頭投票。如果它回答您的問題,請點擊旁邊的複選標記接受答案。 – 2015-02-07 14:43:18