我知道使用Javascript promises加载返回的Firebase对象有很多问题和答案,但我没有成功捕获数组中的数据。
问题:我已设置一个数组(下面为Run Functional Tests
)以迭代方式接收Firebase快照的值,但退出{{1}后数组仍为空}循环。
database.js:
productArray
问题:我认为我使用的是forEach
错误,但无法弄清楚如何(也是新的异步函数)。感谢您提供有关如何成功加载 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());
});
});
}
的任何提示。
修改:详细说明,似乎Promise.all
正在加载正确的Firebase数据,productArray
正在循环遍历snapshot
中的每个项目,但forEach
在snapshot
语句之外变为(或保持)为空。
更新我实现了以下所有建议,但程序将不会停止足够长时间从快照对象构建数组。去年我使用了Angularfire的productArray
函数,该函数在让程序等待方面非常有效,所以我不明白为什么普通的JS Promise.all
在这里不起作用。诉诸$loaded
是否有意义?我甚至试图结合alexmac和Pointy的建议,但没有雪茄:
promise
答案 0 :(得分:1)
我认为你错过了对promises和Firebase SDK的理解。
首先,请注意所有Firebase SDK函数都会返回promise,因此无需创建自己的函数。其次,Promise.all是为了结合多个承诺。单个承诺可以通过简单的.then()
链接起来。
我在这里有一个关于保存和查询数据的视频:Save and Query Firebase Data
我还有另一个关于承诺的视频:Promises
您应该在页面的顶部初始化firebase。它只需要初始化一次,所以不要在函数内初始化它。
您可以在页面上加载Firebase SDK后立即致电firebase.initializeApp(config)
。或者您可以参考Firebase Hosting的init.js
,如下所示。
以下示例加载Firebase SDK,使用我的测试db的init.js
文件来初始化firebase,然后查询,操作并返回一个数组。
请注意,Firebase不支持零索引数组,因此从Firebase返回的所有内容都将是未分类的对象。此示例显示了几种不同的返回数据的方法:)
<html>
<head>
<script src="https://www.gstatic.com/firebasejs/4.3.0/firebase.js"></script>
<script src="https://quiver-two.firebaseapp.com/__/firebase/init.js"></script>
<script>
function loadFirebaseArray(path) {
return firebase.database().ref(path).once('value').then(snap => snap.val());
}
function toArray(items) {
return Object.keys(items).reduce((array, key) => {
const value = items[key];
array.push({key, value});
return array;
}, []).sort();
}
loadFirebaseArray('stackoverflow').then(items => {
console.log('items', items);
const asArray = toArray(items);
alert(JSON.stringify(asArray));
const justTheValues = asArray.map(x => x.value).sort();
alert(justTheValues);
});
</script>
</head>
</html>
答案 1 :(得分:0)
一个工作示例可能如下所示:
getProductList = () => {
let loadFBData = () => {
firebase.initializeApp(config);
return new Promise(resolve => {
firebase.database().ref().once('value', resolve);
});
}
let productArray =[];
loadFBData()
.then(snapshot => {
productArray = Object.keys(snapshot).map((key, prod) => prod);
}
在这里,我使用 promisification 为firebase
查询创建承诺。所以loadFBData
返回一个promise,我可以创建一个promise链或使用ES7 async / await等到promise将被用来使用result。