我刚学会了链接'然后'在Javascript中但是我面临的问题是,在上一个块完成之前,最后一个块执行了。 相关代码是:
firebaseRef.once("value")
.then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
//getting key of the child
var pid=childSnapshot.key;
// childData will be the actual contents of the child
var childData = childSnapshot.val();
var name=childData.name;
pids.push(pid);
names.push(name);
});
})
.then(function() {
for (var i = 0; i < pids.length; i++) {
$("#pid"+(i+1)).text(pids[i]);
$("#name"+(i+1)).text(names[i]);
}
set1();
set2();
set3();
set4();
})
.then(function(){
calcAvg();
});
这里,calcAvg()在set1(),set2(),set3(),set4()方法执行之前触发。这给了我不正确的结果。任何人都可以帮我解决这个问题吗?
EDIT1:请在此处查看checkAvg()方法:https://jsfiddle.net/jek9m7hn/。看起来有一些问题。
答案 0 :(得分:1)
看起来set1
正在调用异步的firebase API。
您应该在设置方法中使用Promise.all
来确保所有承诺都已解决,如下所示:
function set1() {
... // calculate stuff
var p1 = guideRef.child("presentation").once('value');
p1.then(...).
... // more calculations
return Promise.all([p1, p2, ...]) // all your async calls
}
然后,在您的主要功能中,您可以执行以下操作:
for (var i = 0; i < pids.length; i++) {
$("#pid"+(i+1)).text(pids[i]);
$("#name"+(i+1)).text(names[i]);
}
return Promise.all([set1(), set2(), set3(), set4()])
我认为重构代码可以降低这种复杂性,但这超出了问题的范围。
答案 1 :(得分:1)
set1
等以异步方式运行,但您不是在等待它们完成。您需要重写set1
以返回完成所有异步工作的承诺,然后将代码更改为
.then(set1).then(set2).then(set3).then(set4).then(calcAvg)
但是,我建议重新编写所有这些代码。您不应该使用DOM作为存储值的主要位置。此外,您应该组合firebase调用,而不是为每个单独的值单独调用。
答案 2 :(得分:-1)
在一个函数内声明的变量然后在链接函数内部无法访问。 JS中的变量具有块作用域,在一个块作用域中声明的变量不能在另一个块作用域内访问。要解决您的问题,您可以尝试在第一个之外声明pid,即按如下方式重构您的代码
var pids = [], names = [];
firebaseRef.once("value")
.then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
//getting key of the child
var pid=childSnapshot.key;
// childData will be the actual contents of the child
var childData = childSnapshot.val();
var name=childData.name;
pids.push(pid);
names.push(name);
});
})
.then(function() {
for (var i = 0; i < pids.length; i++) {
$("#pid"+(i+1)).text(pids[i]);
$("#name"+(i+1)).text(names[i]);
}
set1();
set2();
set3();
set4();
})
.then(function(){
calcAvg();
});