我正在尝试从我的数据库中检索数据。我的代码创建一个空数组,并在每次添加一个子数据时附加一个子数据。然后它创建列表(忽略MDL类)并将其添加到HTML文档中。
<script>
// get emergencies to array
var firebaseRef = firebase.database().ref('Incidents');
var emergencies = [];
// var emergencies = ['Test', 'Test 2', 'Test 3'];
firebaseRef.on('child_added', function(snap) {
snap.forEach(function (childSnap) {
console.log(childSnap.val());
emergencies.push(childSnap.val());
});
});
var opentag = '<ul class="mdl-list" id="emergenciesList">',
closetag = '</ul>',
array = [];
for (i = 1; i <= emergencies.length; i++) {
array[i] = '<li class="mdl-list__item">' + emergencies[i] + '</li>';
}
var newArray = array.join(" ");
document.getElementById('foo').innerHTML = opentag + newArray + closetag;
</script>
奇怪的是,在console.log()语句中,数据检索完全正常,但在字符串操作之后,newArray未定义。救命啊!
答案 0 :(得分:1)
问题是由您订购代码的方式引起的。执行行的顺序与您的想法不同。如果你把它减少到这个,最简单的看法是这样的:
on('child_added'
现在记录日志的顺序是:
在数据库加载开始之前
数据库加载开始后
在child_added
中
这可能不是你所期望的。日志记录按此顺序显示的原因是Firebase异步加载数据。因此,当var firebaseRef = firebase.database().ref('Incidents');
firebaseRef.on('child_added', function(snapshot) {
var ul = document.getElementById("emergenciesList");
if (!ul) {
document.getElementById('foo').innerHTML = '<ul class="mdl-list" id="emergenciesList"></ul>';
ul = document.getElementById("emergenciesList");
}
var li = document.createElement("li");
li.classList.append("mdl-list__item"); // or: li.className = "mdl-list__item"
li.id = snapshot.key;
li.innerText = snapshot.val();
ul.appendChild(li);
});
行开始加载数据时,从Firebase服务器获取该数据可能需要一些时间。浏览器不再等待数据(这将阻止用户与您的应用程序交互的能力),而是继续执行块之后的语句。然后,当数据可用时,它会调用您的回调函数。
处理异步性的一种常见方法是重构你的问题。现在你的代码写成&#34;首先加载数据,然后将其添加到HTML&#34;。尝试将其框架为&#34;开始加载数据。当数据可用时,将其添加到HTML&#34;。这转化为这段代码:
In [12]: df = pd.DataFrame({'a': ['a', 'ab', 'b'],
'c': ['d', 'd', 'd'],
'val': [1, 2 , 3]}).set_index(['a', 'c'])
In [13]: df
Out[13]:
val
a c
a d 1
ab d 2
b d 3
In [15]: df.xs('a', level='a', drop_level=False)
Out[15]:
val
a c
a d 1
In[16]: df.xs(contains('a'), level='a', drop_level=False)
我删除了快照上的循环,因为我不确定它是否需要并且它使代码复杂化。如果您的数据结构需要循环,则可以将其添加回原来的位置。