所以基本上我有一个从firebase检索数据的Web应用程序。并且由于从firebase检索数据需要花费大量时间,因此我使用promise来使我的代码在正确的时间填充。这是我的代码:
var promise = getDataFirebase();
promise.then(function () {
console.log(Collect);
console.log("firsst");
return getDataFirebaseUser();
}).then(function () {
console.log("Second");
});
function getDataFirebase() {
return new Promise(function (resolve, reject) {
refReview.on("value", function (snap) {
var data = snap.val();
for (var key in data) {
Collect.push({
"RevieweeName": data[key].revieweeID.firstname.concat(" ", data[key].revieweeID.lastname),
"ReviewerName": data[key].reviewerID.firstname.concat(" ", data[key].reviewerID.lastname),
rating: data[key].rating,
content: data[key].content,
keyOfReviewee: data[key].revieweeID.userID
})
var getDataToUsers = firebase.database().ref("users").child(data[key].revieweeID.userID);
getDataToUsers.once("value", async function (snap) {
var fnLn = snap.val();
var first = fnLn.isTerminated;
console.log("terminateStatus", first);
});
}//end of for loop
resolve();
}); //end of snap
});
}
所以在函数getDataFirebase中,从firebase检索数据并将其推送到名为Collect的数组。因此,在按下1行之后,它再次向firebase查询另一个数据表,然后继续循环。这里的问题是,我想在结算承诺之前完成所有流程。
根据代码输出的控制台如下:
Collect (array)
first
Second
terminateStatus, 1
一定是
Collect (array)
first
terminateStatus,1
second
答案 0 :(得分:0)
我不是100%确定您的代码是如何工作的,但看起来您在refReview.on("value")
做了正确的事情:在调用Firebase之前创建一个承诺,然后再解析它。但是你没有在getDataToUsers.once("value")
上这样做。在那里,你正在触发事件而不是等待它返回 - for循环继续,所有的回调都在稍后处理,但是resolve
在for循环的末尾,所以它也是那么晚了。
我的猜测是你认为async
关键字会导致for循环等待该作业完成,但实际上它所做的只是导致回调返回一个promise - 这被on
功能。
你有几个选择,但最好的方法是使用Promise.all
,它接受一系列的承诺并等待它们全部解决 - 但你应该使用Firebase's Promise API而不是将承诺捆绑到事件API上。所以它看起来像:
refReview.once('value')
.then(snap => Promise.all(snap.val().map(item =>
firebase.database()
.ref("users")
.child(item.revieweeID.userID)
.once('value')
.then(snap => {
console.log('terminated');
])
})));
(添加了实际功能,natch除外)