Javascript Firebase-通过回调在阵列中检索和存储数据
我想使用Firebase回调从实时数据库中检索数据,将其存储在数组中,然后将该数据用于数据可视化目的。但是当我为数组记录控制台时,它返回空。我试图理解/修复我的错误,但仍然有很多问题Javascript Firebase-通过回调在阵列中检索和存储数据,javascript,arrays,firebase,asynchronous,firebase-realtime-database,Javascript,Arrays,Firebase,Asynchronous,Firebase Realtime Database,我想使用Firebase回调从实时数据库中检索数据,将其存储在数组中,然后将该数据用于数据可视化目的。但是当我为数组记录控制台时,它返回空。我试图理解/修复我的错误,但仍然有很多问题 var genderData=[]; // Get counter values. function getData(){ var ref = firebase.database().ref().child('counters'); return ref.once('value').then((s
var genderData=[];
// Get counter values.
function getData(){
var ref = firebase.database().ref().child('counters');
return ref.once('value').then((snapshot) => {
snapshot.forEach((element) => {
genderData.push(element.val()['Male']);
});
return genderData;
});
}
console.log(genderData);
我的控制台显示:
最后,我希望能够使用我的数组通过chart.js库生成图表:
// Bar graph displaying the total number of students by gender.
var ctx = document.getElementById("myChart4").getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Male", "Female", "Non-Binary", "Other", "Unspecified"],
datasets: [{
data: genderData,
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)',
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
title: {
display: true,
text: 'Total Students by Gender'
},
legend:{
display: false
},
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
我已经研究这个问题好几个小时了,没有解决办法。我只想用我的数据库数据创建一个简单的数组,但我遇到了很多麻烦。我真的希望有人能帮我找到一个优雅的解决方案
编辑:
我的一点数据库结构,以防万一:
Firebase异步加载数据。这意味着需要访问数据的任何代码都必须位于
then()
回调中,或者必须使用自己的then()
回调
使用当前对getData
的定义,您可以调用它并使用以下数据:
getData().then((data) => {
console.log("In callback");
console.log(data);
console.log(genderData);
})
console.log("Outside callback");
console.log(genderData);
如果运行此代码,您将看到:
外部回调
[]
内部回调
[项目1、项目2,…]
[项目1、项目2,…]
这里需要注意的是:
外部回调
代码在内部回调
代码之前运行,这可能不是您所期望的genderData
和data
是相同的。这是因为您在回调中返回genderData
,然后将其冒泡到then()
方法然后回调中的一个回调中,以便在加载数据后调用它。例如:
getData().then((data) => {
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Male", "Female", "Non-Binary", "Other", "Unspecified"],
datasets: [{
data: data,
...
Firebase异步加载数据。这意味着需要访问数据的任何代码都必须位于then()
回调中,或者必须使用自己的then()
回调
使用当前对getData
的定义,您可以调用它并使用以下数据:
getData().then((data) => {
console.log("In callback");
console.log(data);
console.log(genderData);
})
console.log("Outside callback");
console.log(genderData);
如果运行此代码,您将看到:
外部回调
[]
内部回调
[项目1、项目2,…]
[项目1、项目2,…]
这里需要注意的是:
外部回调
代码在内部回调
代码之前运行,这可能不是您所期望的
回调之外的代码运行时,数组仍然为空。只有在回调中的代码运行之后,数组才会包含数据
在回调内部,genderData
和data
是相同的。这是因为您在回调中返回genderData
,然后将其冒泡到then()
方法
最终的解决方案是,创建图表的代码(您需要数据的地方)应该位于然后回调中的一个回调中,以便在加载数据后调用它。例如:
getData().then((data) => {
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Male", "Female", "Non-Binary", "Other", "Unspecified"],
datasets: [{
data: data,
...
如果将值推送到数组中,为什么还要返回它?如果将值推送到数组中,为什么还要返回它?这很有意义。但我认为现在我遇到了一个不同的问题:当我按照您的建议记录数据时,我所有的值都是未定义的(并且有太多的值——54个,而应该有13个)。这可能是什么原因造成的?为了以防万一,我添加了一个数据库结构的屏幕截图。我猜您多次调用getData()
,每次都将所有项目添加到genderData
。但这只是一个猜测。请注意,所有这些都与chart.js库本身无关,因此我建议查看以减少问题的范围。是的,我相信这是forEach
循环。我删除了它,只做了genderData.push(snapshot.val()['Male'])代码>,现在我的控制台似乎正在按预期记录日志(我希望如此)。这里是一个截图:这很有意义。但我认为现在我遇到了一个不同的问题:当我按照您的建议记录数据时,我所有的值都是未定义的(并且有太多的值——54个,而应该有13个)。这可能是什么原因造成的?为了以防万一,我添加了一个数据库结构的屏幕截图。我猜您多次调用getData()
,每次都将所有项目添加到genderData
。但这只是一个猜测。请注意,所有这些都与chart.js库本身无关,因此我建议查看以减少问题的范围。是的,我相信这是forEach
循环。我删除了它,只做了genderData.push(snapshot.val()['Male'])代码>,现在我的控制台似乎正在按预期记录日志(我希望如此)。以下是一个屏幕截图: