2015-02-07 51 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