【发布时间】:2018-01-29 20:47:06
【问题描述】:
我知道有很多关于使用 Javascript 承诺加载返回的 Firebase 对象的问题和答案,但我还没有成功捕获数组中的数据。
问题:我已经设置了一个数组(下面的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());
});
});
}
问题:我认为我使用 Promise.all 错误,但不知道如何(也是新的异步函数)。感谢您提供有关如何让productArray 成功加载的任何提示。
编辑: 详细地说,snapshot 似乎正在加载正确的 Firebase 数据,forEach 正确循环通过 snapshot 中的每个项目,但 productArray 变为(或仍然)在Promise.all 语句之外为空。
更新我实现了以下所有建议,但程序不会停止足够长的时间来从快照对象构建数组。去年我使用了 Angularfire 的 $loaded 函数,它在让程序等待方面非常有效,所以我不明白为什么普通的 JS promise 在这里不起作用。求助于timeout 有意义吗?我什至尝试结合 alexmac 和 Pointy 的建议,但没有雪茄:
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();
}
【问题讨论】:
-
乍一看,这段代码看起来不错。它只会使用一个承诺,因为您正在加载整个数据库。但这应该可行,除非我忽略了某些东西。这段代码有什么问题?
-
@Frank,感谢您的回复。详细地说,
snapshot确实在加载 Firebase 数据。问题在于(或必须)在forEach循环中,因为(在Promise.all之后和getProductList()内部),productArray.length返回 0。 -
您的代码实际上根本没有做出承诺。
loadFBData()函数需要使用 Promise 回调中的当前代码返回一个新的 Promise。该函数应将检索到的数据传递给resolve()函数。 -
为什么你只对一个元素使用
Promise.all?此外,如果firebase.database().ref().once返回一个承诺,则您根本不需要Promise.all。 -
标签: javascript firebase firebase-realtime-database promise