Firebase查询内部函数返回null

时间:2015-02-07 10:23:25

标签: javascript oop firebase

我正在尝试使用带有firebase的javascript创建学生出勤跟踪器应用程序。

但我有一个问题,我正在尝试查询函数内部并让函数返回这些数据。

但是当我尝试时,它什么都不返回。 '未定义'

这是我的代码

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);
    }
}

我不知道为什么它不能以面向对象的方式提取数据。

任何输入?

感谢。

1 个答案:

答案 0 :(得分:4)

你所看到的与OO没什么关系,但Firebase与大多数现代网络一样的事实本质上都是异步的。

使用on向Firebase注册事件处理程序时,Firebase 启动以检索并监控该位置的数据。由于可能需要一些时间来检索数据(并且更新的数据可能随时到达),浏览器将继续执行您的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等内容更新您的用户界面。

另请阅读此答案(它使用的是AngularFire,但问题是相同的):Asynchronous access to an array in Firebase以及其中一些其他问题。

相关问题