我正在尝试在循环和外部firebase调用内部进行Firebase数据库调用 . 内部Firebase数据库调用使用从外部firebase调用和循环返回的数据,这就是它在外部运行的原因 . 然后应该将结果设置为状态 .
Problem 未在状态中设置内部Firebase数据库调用中检索的值 .
Theory 由于Firebase数据库调用是异步的,我猜测内部Firebase数据库调用在循环完成并设置状态之前没有完成 . 因此,我为内部Firebase数据库调用创建了一个承诺,以便循环将等待调用完成,然后再转到下一个项目 . 但是,检索的值仍未设置 .
有谁知道为什么循环不等待包含对Firebase数据库的调用的承诺?
MY ATTEMPT
userRef.on("value", function(snapshot) {
var snap = [];
// loop through each branch received from firebase
snapshot.forEach(function(data) {
var firstThingsFirst = data.val().firstThingsFirst;
var someID = data.val().someID;
var myPromise = new Promise(function(resolve, reject) {
userRef.child('somechild').child(someID).once('value').then(function(newSnapshot) {
console.log("newSnapshot = (below)");
console.log(newSnapshot.val());
resolve(newSnapshot.val());
}, function(error) {
// Something went wrong.
console.error("error (below)");
console.error(error);
reject("noValueFound")
});
});
var someValue = "";
myPromise.then(function(valueRetrieved) {
console.log(".then of promise is running...");
console.log("valueRetrieved = (below)");
console.log(valueRetrieved);
someValue = this.checkUndefined(valueRetrieved);
}.bind(this));
var array = {"firstThingsFirst": firstThingsFirst, "someValue": someValue};
snap.push(array);
});
this.setState({
snapshots: snap
});
}.bind(this));
Alternative Attempt:
userRef.on("value", function(snapshot) {
var snap = [];
// loop through each branch received from firebase
snapshot.forEach(function(data) {
var firstThingsFirst = data.val().firstThingsFirst;
var someID = data.val().someID;
var someValue = this.fetchValueByID(someID);
var array = {"firstThingsFirst": firstThingsFirst, "someValue": someValue};
snap.push(array);
});
this.setState({
snapshots: snap
});
}.bind(this));
fetchValueByID(someID) {
userProfileRef.child('someChild').child(someID).once('value').then(function(snapshot) {
console.log("snapshot (fetchValueByID) = (below)");
console.log(snapshot.val());
return snapshot.val();
})
}
我也尝试过Firebase推荐的方法:
提前致谢 .
1 回答
这样做的原因是在完成所有提取后需要调用
setState
. 但是,你的代码没有做任何等待的事情 . 你只需继续循环,一旦完成,调用setState
. 你真的不知道你的提取是否完成 . 你需要一种方法来等待所有的提取 . 简而言之,由于同步和异步代码的混合存在问题 .你可以试试这个 . 我的想法是将所有
fetchValueByID
(我在开头添加了一个return
)调用映射到一个promises数组,然后在执行setState
之前等待所有这些调用(使用Promise.all)我伪造了所有可能的数据,并将我的解决方案转换为下面简单易懂的代码段