这是我的数据结构:
使用Total
(计数为R
aka路由)我使用此处的代码生成3个输入框:
var rootRef = firebase.database().ref().child('Lane').child('Total')
function calcVelocity(snapshot) {
var td;
td = snapshot.val();
return td;
}
function getVelocity() {
return rootRef.once('value').then(calcVelocity);
}
getVelocity().then(function(vel) {
for(i =0; i < vel; i ++){
document.getElementById("insert_lanes").innerHTML += '<input type="text" class="form-control" id="R'+i+'" name="Schoolname[]" value="" placeholder="Freq Rank"><br>'
}
工作正常,有3个输入框使用ID R1
R2
R3
生成。
现在加载数据:
function f1(snapshot){
var hol;
hol = snapshot.val();
return hol
}
function f2(i){
return firebase.database().ref('Lane/R'+i+"/Dest").once('value').then(f1)
}
for(y =0; y<3; y++){
f2(y).then(function(veg){
document.getElementById("R"+y).value = veg;
})
}
会引发错误Uncaught (in promise) TypeError: Cannot set property 'value' of null
然而,当我只对其中一个人这样做时,它可以工作:
function f1(snapshot){
var hol;
hol = snapshot.val();
return hol
}
function f2(i){
return firebase.database().ref('Lane/R'+i+"/Dest").once('value').then(f1)
}
y=1
f2(y).then(function(veg){
document.getElementById("R"+y).value = veg;
})
我不明白什么是错的。
答案 0 :(得分:1)
我很确定问题出在你的for循环中。当promises返回时,问题可能是for循环中的y变量的范围问题。尝试展开for循环,看看是否有效:
f2(0).then(function(veg){
document.getElementById("R"+ 0).value = veg;
}));
f2(1).then(function(veg){
document.getElementById("R"+ 1).value = veg;
}));
f2(2).then(function(veg){
document.getElementById("R" + 2).value = veg;
}));
答案 1 :(得分:1)
我将分两部分打破我的回答:问题和解决方案。
问题在于firebase
函数的异步调用。让我们做一些挖掘,这将使事情变得清晰。我添加了一些console
输出以查看其中的位置。请注意,我还在这些函数之外声明y
以跟踪循环迭代。
var y = 0;
function f1(snapshot) {
console.log("in f1", y);
var hol;
hol = snapshot.val();
console.log("in f1 hol", hol, y);
return hol;
}
function f2(i) {
console.log("in f2", y);
return firebase.database().ref('Lane/R' + i + "/Dest").once('value').then(f1);
}
for (; y < 3; y++) {
console.log("in for", y);
f2(y).then(function(veg) {
console.log("resolved", y);
document.getElementById("R" + y).value = veg;
console.log(y);
})
}
f1
函数仅在firebase
的异步调用解析后运行(then
执行此操作)。因此,这个请求可以在某个队列中进行,但这并不会阻止其他函数执行,因为工作已经完成并且请求已由f2
发出。如果您看到图片并将其与代码相关联,您会看到我们开始从firebase
获得响应,y
的时间值已递增并达到3
。然后执行document.getElement
,但只考虑y
的最终值,所有其他值现在都已过去。在其他情况下,可能会发生这种情况可能会在循环结束时得到/未得到解决。这会导致不一致。
对于一个值,它是直接的,因为只有一个值需要解析,一个相应的字段要填充。所以没有不一致之处。简而言之,这是不可预测的。
让我们回顾一下另一个并发问题。显然,当您访问输入字段以填充它们时,它们甚至都不存在!它们尚未添加到DOM中。这又是解决回调或承诺的复杂情况。
这可能是Uncaught (in promise) TypeError: Cannot set property 'value' of null
即将到来的原因。
看一下下面这段代码。我试图尽可能少地改变并使其发挥作用。
<强> getVelocity 强>
getVelocity().then(function(vel) {
//pass the value of Total in vel
for (var i = 0; i < vel; i++) { //vel = 5
document.getElementById("insert_lanes").innerHTML += '<input type="text" class="form-control" id="R' + i + '"><br>';
}
// the input fields are created R0, R1, ......
loadSnapshot(); //calling the next function
});
之后
var laneRef = firebase.database().ref('/Lane');
var getSnap = function(){
return laneRef.once('value');
}
function loadSnapshot(){
getSnap().then(fillInputFields);
}
function fillInputFields(snapshot){
for(var i=0; i<5; i++) {
var v = snapshot.child('R'+i).child('Dest').val();
// console.log(v);
// console.log((document).getElementById('R'+i));
document.getElementById('R'+i).value = v;
}
}
我希望这会奏效!试一试。