所以基本上我有一个从firebase检索数据的Web应用程序。由于查询需要时间,我在javascript中使用了promises,以便我的代码在正确的时间执行。在函数getDataFirebase中,从firebase检索数据并将其推送到名为Collect的数组。因此,在推送1行之后,它再次向firebase查询要收集的另一个数据表,然后继续循环。所以,我在致电Firebase之前创建了一个承诺,然后再解决。但是,我没有在getDataUsers.once上做到这一点("值")。在那里,我正在触发事件而不是等待它返回 - for循环继续,并且所有回调都在稍后处理,但是解析是在for循环结束时,所以到那时为时已晚。
我在查询时使用了async关键字,希望它会导致for0loop等待该作业完成,但实际上它所做的全部操作都会导致回调返回一个承诺 - 由on函数加入。它已经调试了一段时间,并希望它能在适当的时间填充执行。有人请帮帮我吗? :(((
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
});
}
根据代码输出控制台如下:
Collect(array)
first
Second
terminateStatus, 1
一定是
Collect(array)
first
terminateStatus, 1
second
答案 0 :(得分:0)
首先,你误解了javascript中async / await的概念。请阅读mozilla的这个manual和一些例子来了解如何使用它。
回到你的问题,在你的例子中向回调函数添加“async”关键字不会改变任何东西。如果异步与否,Firebase将以相同的方式获取数据时调用该函数。在获取数据之前,在for循环结束时调用resolve
,完成承诺。因此,在您获取数据之前,承诺已得到解决,这就是您最终获得terminateStatus
的原因。
您可以使用从once
方法返回的Promise,并等待它以便它不会退出for循环,直到获取所有数据。为此,您需要在第一次回调中添加async
。见:
function getDataFirebase() {
return new Promise(function (resolve, reject) {
refReview.on("value", async 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);
var snapshot = await getDataToUsers.once("value");
var fnLn = snapshot.val();
var first = fnLn.isTerminated;
console.log("terminateStatus", first);
}//end of for loop
resolve();
}); //end of snap
});
}
但是,这仍然不是很好的代码,因为每次在不同的promise中调用refReview.on
方法。您应该在应用程序中调用一次并附加回调,或者如果您打算为每个调用获取一个文档,则应使用refReview.once
方法。