我知道使用Javascript promises加载返回的Firebase对象有很多问题和答案,但我没有成功捕获数组中的数据 .
The issue: 我已经设置了一个数组(下面的 productArray
)来迭代地接收Firebase快照的值,但是在退出 forEach
循环后该数组仍然为空 .
database.js:
getProductList = function(){
let productArray =[];
loadFBData = function(){
firebase.initializeApp(config);
return firebase.database().ref().once("value", function(snapshot){
return snapshot.val();
});
}
Promise.all([loadFBData()]).then(function(snapshot) {
snapshot.forEach(function(product) {
productArray.push(product.val());
});
});
}
Question: 我认为我使用 Promise.all
错误,但无法弄清楚如何(也是新的异步函数) . 感谢您提供有关如何成功加载 productArray
的任何提示 .
Edit: 为了详细说明,似乎 snapshot
正在加载正确的Firebase数据,并且 forEach
正确循环遍历 snapshot
中的每个项目,但 productArray
在 Promise.all
语句之外变为(或保持)为空 .
Update 我实现了下面的所有建议,然而,程序将不会停留足够长的时间来从快照对象构建数组 . 去年我使用了Angularfire的 $loaded
函数,它在程序等待方面非常有效,所以我不明白为什么普通的JS promise
在这里不起作用 . 诉诸 timeout
是否有意义?我甚至试图结合alexmac _2883431的建议,但没有雪茄:
getProductList = function(){
let productArray =[];
loadFBData = function(){
firebase.initializeApp(config);
return new Promise(resolve => {
firebase.database().ref().once('value')
.then(function(snapshot){
return resolve(function(snapshot){
productArray = Object.keys(snapshot).map((key, prod) => prod);
});
});
});
}
loadFBData();
}
2 回答
一个工作示例可能如下所示:
在这里,我使用promisification为
firebase
查询创建一个承诺 . 所以loadFBData
返回一个promise,我可以创建一个promise链或使用ES7 async / await等到promise将被用来使用result .背景
我认为你错过了对promises和Firebase SDK的理解 .
首先,请注意所有Firebase SDK函数都会返回promise,因此无需创建自己的函数 . 其次,Promise.all是为了结合多个承诺 . 单个承诺可以通过简单的
.then()
链接起来 .我在这里有关于保存和查询数据的视频:Save and Query Firebase Data
我在这里有另一个关于承诺的视频:Promises
加载Firebase
您应该在页面的顶部初始化firebase . 它只需要初始化一次,所以不要在函数内初始化它 .
您可以在页面上加载Firebase SDK后立即致电
firebase.initializeApp(config)
. 或者您可以参考Firebase Hosting的init.js
,如下所示 .示例
以下示例加载Firebase SDK,使用我的测试db的
init.js
文件初始化firebase,然后查询,操作并返回一个数组 .请注意,Firebase不支持零索引数组,因此从Firebase返回的所有内容都将是未分类的对象 . 这个例子显示了一些返回数据的不同方法:)