【问题标题】:Firebase Query inside function returns null函数内部的 Firebase 查询返回 null
【发布时间】:2015-04-07 11:52:18
【问题描述】:

我正在尝试使用带有 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);
    }
}

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

有什么意见吗?

谢谢。

【问题讨论】:

    标签: javascript oop firebase


    【解决方案1】:

    您所看到的与 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 之类的内容更新您的 UI。

    还阅读了这个答案(它使用的是 AngularFire,但问题是一样的):Asynchronous access to an array in Firebase 以及从那里链接的其他一些问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-29
      • 1970-01-01
      • 2020-06-03
      • 1970-01-01
      相关资源
      最近更新 更多