Promisify google.charts.setOnLoadCallback

时间:2016-03-26 13:56:34

标签: javascript charts promise google-visualization

我一直在使用谷歌的图表API,并已达到死胡同。我使用API​​查询电子表格并返回一些数据。对于可视化,我使用Razorflow - 一个JS仪表板框架 - 而不是Google Charts。使用这样的代码获取数据非常简单(此代码应该可以使用 - 电子表格是公开的):

function initialize() {
// The URL of the spreadsheet to source data from.
var myKey = "12E2fE8GWuPvXJoiRZgCZUCFhRKlW69uJAm7fch71jhA"
var query = new google.visualization.Query("https://docs.google.com/spreadsheets/d/" + myKey + "/gviz/tq?sheet=Sheet1");
query.setQuery("SELECT A,B,C WHERE A>=1 LIMIT 1");
query.send(function processResponse(response) {

    var KPIData = response.getDataTable();
    var KPIName = [];
    myNumberOfDataColumns = KPIData.getNumberOfColumns(0) - 1;        

        for (var h = 0; h <= myNumberOfDataColumns ; h++) {
        KPIName[h] = KPIData.getColumnLabel(h);
    };  
});
};     
google.charts.setOnLoadCallback(initialize);

上面将创建一个包含A,B和C列的列标签的数组。

获取数据后,我想将数据用于我的图表。问题是,我需要在创建图表之前准备好数据。我这样做的一种方法是在调用google.charts.setOnLoadCallback(initialize)之前创建图表,然后使用回调内部的数据填充图表。像这样:

//create dashboard
StandaloneDashboard(function (db) {
//create chart - or in this case a KPI
var firstKPI = new KPIComponent();
//add the empty component
db.addComponent(firstKPI);
//lock the component and wait for data
firstKPI.lock();


function initializeAndPopulateChart() {
// The URL of the spreadsheet to source data from.
var myKey = "12E2fE8GWuPvXJoiRZgCZUCFhRKlW69uJAm7fch71jhA"
var query = new google.visualization.Query("https://docs.google.com/spreadsheets/d/" + myKey + "/gviz/tq?sheet=Sheet1");
query.setQuery("SELECT A,B,C WHERE A>=1 LIMIT 1");
query.send(function processResponse(response) {

    var KPIData = response.getDataTable();
    var KPIName = [];
    myNumberOfDataColumns = KPIData.getNumberOfColumns(0) - 1;        

        for (var h = 0; h <= myNumberOfDataColumns ; h++) {
        KPIName[h] = KPIData.getColumnLabel(h);
    };
    //use label for column A as header
    firstKPI.setCaption(KPIName[0]);
    //Set a value - this would be from the query too
    firstKPI.setValue(12);
    //unlock the chart
    firstKPI.unlock();  
});
};     
google.charts.setOnLoadCallback(initializeAndPopulateChart);
});

它有效,但我想将图表功能与数据加载分开。我想最好的解决方案是创造一个承诺。这样我可以做这样的事情:

//create dashboard
StandaloneDashboard(function (db) {

function loadData() {
return new Promise (function (resolve,reject){
    //get the data, eg. google.charts.setOnLoadCallback(initialize);
})
}

loadData().then(function () {
    var firstKPI = new KPIComponent();
    firstKPI.setCaption(KPIName[0]);
    firstKPI.setValue(12);
    db.addComponent(firstKPI); 
    })
});

应该很明显,我不完全了解如何使用promises。以上不起作用。我尝试了很多不同的方法但是,我似乎没有更接近解决方案。我是否正在使用承诺?如果是这样,我应该怎么做呢?

2 个答案:

答案 0 :(得分:0)

在承诺内部,您需要在异步作业完成时调用resolvereject函数。

function loadData() {
  return new Promise (function (resolve,reject){
    query.send(function() {
      //...
      err ? reject(err) : resolve(someData);
    });
  })
}

然后你可以做

loadData().then(function (someData) {
    //here you can get async data
  }).catch(function(err){
    //here you can get an error
  });
});

答案 1 :(得分:0)

new Promise(resolve => {
    google.charts.setOnLoadCallback(resolve);
}).then(getValues);