从Firebase读取嵌套数据会返回数组以外的内容 [英] Reading nested data from Firebase returns something else than an array

查看:59
本文介绍了从Firebase读取嵌套数据会返回数组以外的内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试读取(并期望)这样的嵌套数组:

Trying to read (and expect) a nested array like this:

var array = [
0: {subArrayy: {...}, title: "Title"}, 
1: {subArray]: {...}, title: "Title"},
...

但是,在读取和(!)输出之后,结果还是不错的.我的Web控制台向我显示了阵列,一切似乎都很好.但是执行array.length返回0.并且任何迭代都返回undefined.

However after reading and (!) outputting, the result is fine. My web console shows me the array and everything seems good. BUT doing array.length returns 0. And any iteration returns undefined.

我已经尝试使用我以前见过的ladosh _.toArray东西,但是它绝对没有作用.

I've tried using ladosh _.toArray thing that I've seen earlier, but it does absolutely nothing.

var locations = []; // Empty array

  var ref = db.ref("locations/");
  ref.once("value", function(snapshot) {

    snapshot.forEach(function(item) {
      var itemVal = item.val();
      locations.push(itemVal); // Adding new items seems to work at first

    });

  });
  console.log(locations, locations.length);

输出:

chrome输出

我希望它是可迭代的,因为我可以只使用数组 0 进行导航.

I expected it to be iterable, in the way I could just use array0 to navigate.

推荐答案

Firebase异步读取数据,因此在等待网络流量时不会阻止该应用程序.然后,一旦数据加载完毕,它将调用您的回调函数.

Firebase reads data asynchronously, so that the app isn't blocked while waiting for network traffic. Then once the data is loaded, it calls your callback function.

您可以通过放置一些日志语句来轻松地看到这一点:

You can easily see this by placing a few log statements:

console.log("Before starting to load data");
ref.once("value", function(snapshot) {
  console.log("Got data");
});
console.log("After starting to load data");

运行此代码时,输​​出为:

When you run this code the output is:

开始加载数据之前

Before starting to load data

开始加载数据后

获得数据

这可能不是您期望的顺序,但是它准确地解释了为什么在记录日志时会得到零长度的数组.但是由于主要代码立即继续进行,因此到您console.log(locations, locations.length)尚未加载数据,并且尚未将其推入数组时.

This is probably not the order you expected, but it explains exactly why you get a zero length array when you log it. But since the main code continued on straight away, by the time you console.log(locations, locations.length) the data hasn't loaded yet, and you haven't pushed it to the array yet.

解决方案是确保所有需要数据的代码都在回调内部,或者从那里调用.

The solution is to ensure all code that needs data from the data is either inside the callback, or is called from there.

所以这将起作用:

var locations = []; // Empty array

var ref = db.ref("locations/");
ref.once("value", function(snapshot) {

  snapshot.forEach(function(item) {
    var itemVal = item.val();
    locations.push(itemVal);
  });

  console.log(locations, locations.length);

});

这将会:

function loadLocations(callback) {
  var locations = []; // Empty array

  var ref = db.ref("locations/");
  ref.once("value", function(snapshot) {
    snapshot.forEach(function(item) {
      var itemVal = item.val();
      locations.push(itemVal);
    });
    callback(locations);
  });
});

loadLocations(function(locations) {
  console.log(locations.length);
});

最后一个代码段的一个更现代的变体是返回一个Promise,而不是传递回调.

A more modern variant of that last snippet is to return a promise, instead of passing in a callback.

function loadLocations() {
  return new Promise(function(resolve, reject) {
    var locations = []; // Empty array

    var ref = db.ref("locations/");
    ref.once("value", function(snapshot) {
      snapshot.forEach(function(item) {
        var itemVal = item.val();
        locations.push(itemVal);
      });
      resolve(locations);
    });
  })
});

然后您可以这样称呼它:

And you can then call it like this:

loadLocations().then(function(locations) {
  console.log(locations.length);
});

或者使用现代JavaScript,您可以使用 async/await 并执行:

Or with modern JavaScript you can use async / await and do:

let locations = await loadLocations()
console.log(locations.length);

请记住,最后一个代码片段仍然具有相同的异步行为,并且JavaScript运行时(或编译器)只是向您隐藏了它.

Just keep in mind that this last snippet still has the same asynchronous behavior, and the JavaScript runtime (or transpiler) is just hiding it from you.

这篇关于从Firebase读取嵌套数据会返回数组以外的内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆