尝试读取(并期望)像这样的嵌套数组:
var array = [
0: {subArrayy: {...}, title: "Title"},
1: {subArray]: {...}, title: "Title"},
...
但是,在读取和(!)输出之后,结果还是不错的。我的Web控制台向我显示了阵列,一切似乎都很好。但是执行array.length返回0。任何迭代都返回undefined。
我已经尝试使用我之前见过的ladosh _.toArray东西,但是它绝对没有作用。
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);
输出:
我希望它是可迭代的,因为我可以使用数组0进行导航。
答案 0 :(得分:0)
放置睡眠功能约300毫秒似乎可以解决此问题。我认为这与同步有关,尽管并不完全确定。我想这只需要一些时间来处理查询并分配所有内容。
答案 1 :(得分:0)
Firebase异步读取数据,因此在等待网络流量时不会阻止该应用程序。然后,一旦数据被加载,它将调用您的回调函数。
通过放置一些日志语句,您可以轻松地看到这一点:
console.log("Before starting to load data");
ref.once("value", function(snapshot) {
console.log("Got data");
});
console.log("After starting to load data");
运行此代码时,输出为:
开始加载数据之前
开始加载数据后
获得数据
这可能不是您期望的顺序,但是它准确地解释了为什么在记录日志时会得到零长度的数组。但是由于主代码会立即继续,所以到您console.log(locations, locations.length)
数据还没有加载,并且还没有将其推送到数组时。
解决方案是确保所有需要数据的代码都在回调内部,或者从那里调用。
这将起作用:
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,而不是传递回调。
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);
});
})
});
然后您可以这样称呼它:
loadLocations().then(function(locations) {
console.log(locations.length);
});
或者使用现代JavaScript,您可以使用async
/ await
并执行以下操作:
let locations = await loadLocations()
console.log(locations.length);
请记住,最后一个代码片段仍然具有相同的异步行为,并且JavaScript运行时(或编译器)只是向您隐藏了它。
答案 2 :(得分:0)
使用等待读取功能似乎也有帮助。