Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/401.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Firebase-通过回调在阵列中检索和存储数据_Javascript_Arrays_Firebase_Asynchronous_Firebase Realtime Database - Fatal编程技术网

Javascript 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

我想使用Firebase回调从实时数据库中检索数据,将其存储在数组中,然后将该数据用于数据可视化目的。但是当我为数组记录控制台时,它返回空。我试图理解/修复我的错误,但仍然有很多问题

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']),现在我的控制台似乎正在按预期记录日志(我希望如此)。以下是一个屏幕截图: