简体   繁体   English

如何 Promise 链接多个 google.charts.setOnLoadCallback 的?

[英]How to Promise chain multiple google.charts.setOnLoadCallback's?

I am using Google's Firestore to obtain data and then using google.charts.setOnLoadCallback to plot the data.我正在使用 Google 的 Firestore 获取数据,然后使用google.charts.setOnLoadCallback来 plot 数据。 The first drawing function draw1 calls for the data, and then the other draw2 and draw2 should reuse the same data.第一张图 function draw1调用数据,然后其他draw2draw2应该重用相同的数据。

I tried Promise chaining the three google.charts.setOnLoadCallback calls, in order to assure that the second and third calls get executed after the first in order to be sure I have the data passed through.我尝试 Promise 链接三个google.charts.setOnLoadCallback调用,以确保第二个和第三个调用在第一个调用之后执行,以确保我传递了数据。 The console logs should show 1, 2, 3, 4 as the order of execution, but instead, I get back 3, 4, 1, 2 - and the Step 3 and 4 have undefined data being passed to them - as the first two Promises have not finished running and the data does not exist yet.控制台日志应该显示 1、2、3、4 作为执行顺序,但相反,我返回 3、4、1、2 - 并且步骤 3 和 4 将未定义的数据传递给它们 - 作为前两个Promise 还没有运行完,数据还不存在。

Is it possible to daisy chain google.charts.setOnLoadCallback Promises?是否可以菊花链google.charts.setOnLoadCallback Promises? See code example below:请参见下面的代码示例:

function initFirebase() {
    // Initialize Cloud Firestore through Firebase
    firebase.initializeApp({
        apiKey: "MyKey",
        authDomain: "MyDomain",
        projectId: "MyProject",
    });
    return firebase.firestore();
}

const getFirebaseData = db => {
    var doc_ref = db.collection('collection').doc('doc'); 
    var queryLimit = doc_ref.orderBy("field1", "desc").limit(10);
    var field1Arr = [];
    var field2Arr = [];

    return queryLimit.get()
        .then(querySnapshot => {
            querySnapshot.forEach(doc => {
                var data = doc.data();
                field1Arr.push(data.field1);
                field2Arr.push(data.field2);
            });
            
            dataArr.push(field1Arr, field2Arr);
            console.log("#1: Returning Data Array from Firebase", dataArr);
            return dataArr; 
       });
}

function draw1() {
    var db = initFirebase();
    getFirebaseData(db).then(data => {
        console.log("#2: Draw 1 Data: ", data);
        return data;
    }); 
}
        
function draw2(data) {
    console.log("#3: Draw 2 Data: ", data);
    return data;
}

function draw3(data) {
    console.log("#4: Draw 3 data: ", data);
    return data;
}


google.charts.load('current', {
    packages: ['corechart', 'line']
});
        
google.charts.setOnLoadCallback(draw1)
    .then(function(data) {
        google.charts.setOnLoadCallback(draw2(data));
    })
    .then(function(data) {
        google.charts.setOnLoadCallback(draw3(data));
    });

The following are in my header:以下是我的header:

<script src="https://www.gstatic.com/charts/loader.js"></script>    
<script src="https://www.gstatic.com/firebasejs/8.1.2/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.1.2/firebase-firestore.js"></script>

Update更新

If I add return new Promise to the draw functions then I am able to execute it in the right order, but the data is not passed from #3 to #4 now.如果我将return new Promise添加到绘制函数中,那么我就能够以正确的顺序执行它,但现在数据并未从#3 传递到#4。

function draw1() {
    return new Promise (function (resolve,reject){
        var db = initFirebase();
        getFirebaseData(db).then(data => {
            console.log("#2: Draw 1 Data: ", data);
            resolve(data)
            return data;
        });
}
        
function draw2(data) {
    return new Promise (function (resolve,reject){
        console.log("#3: Draw 2 Data: ", data);
        resolve(data);
        return data;
    });
}

function draw3(data) {
    return new Promise (function (resolve,reject){
        console.log("#4: Draw 3 Data: ", data);
        resolve(data);
        return data;
    });
}

There's an error with your usage of setOnLoadCallback .您对setOnLoadCallback的使用有误。 As mentioned here the purpose of setOnLoadCallback is to call a function that will be executed once the libraries have been loaded, it's not required to use it every time you draw a graph, instead use the draw method for creating the graph.正如这里提到的, setOnLoadCallback的目的是调用一个 function,一旦加载库就会执行,不需要每次绘制图形时都使用它,而是使用draw方法创建图形。

My suggestion is to create a function that gathers all the data from Firestore, which will be called from the setOnLoadCallback , and once the data has been gathered call the subsequent draw2, draw3 functions from there.我的建议是创建一个 function 来收集来自 Firestore 的所有数据,这将从setOnLoadCallback调用,一旦收集到数据,就会从那里调用后续的 draw2、draw3 函数。

A revamp of your code could be something like:修改您的代码可能是这样的:

google.charts.setOnLoadCallback(draw1);

function draw1() {
    var db = initFirebase();
    getFirebaseData(db).then(data => {
        console.log("#2: Draw 1 Data: ", data);
        let dataFromDB  = modifyDataFromDB(data); //Here you should modify your data to use on the addRows method in the next two functions
        draw2(data);
        draw3(data);
    }); 
}

function draw2(dataFromDB) {
      //Create here your graph 2 with the data sent use the draw method
      data = new google.visualization.DataTable();
      data.addColumn('string', 'Column1');
      data.addColumn('number', 'Column2');
      data.addRows(dataFromDB); //I'm assuming here that the data from Firestore has already the format required

      var options = {
        'title': 'Graph Title',
        'width': 400,
        'height': 300
      };

      chart = new google.visualization.PieChart(document.getElementById('chart_div'));
      google.visualization.events.addListener(chart, 'select', selectHandler);
      chart.draw(data, options);
}

function draw3(dataFromDB){
     //Create here your graph 3 with the data sent use the draw method
}

The code on the draw2 function is just an example of how it would look a function that creates a graph so you can understand a little bit better what goes there. draw2 function 上的代码只是创建图形的 function 的外观示例,因此您可以更好地理解其中的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM