使用承诺对Google表格进行多次查询

时间:2016-02-09 05:22:22

标签: asynchronous google-apps-script google-sheets promise google-query-language

我是初学者编码员,希望能够加快我的Google表格查询速度。我环顾四周,无法找到解决方案。我正在尝试快速向Google表单运行25个查询,这就是我正在尝试的方式:

  1. 运行查询到Google表格。
  2. 将结果推送到数组。
  3. 运行其他查询。
  4. 将结果推送到同一个数组。
  5. 运行下一个查询... x 25.
  6. 绘制最终结果的表格。
  7. 问题是如果我逐个运行quires,他们需要25秒才能完成。如果我在for循环中运行quires,结果会在2秒内返回,但是异步,并且数据全部都没有了。也许,我应该使用承诺或其他东西。请帮忙。

    以下是慢速版本的代码:

    Time.now

    以下是以异步方式返回结果的快速版本:

       var resultData;
    var allData = [];
    var i = 0;
    
    function startQuery() {
      i = 0;
      allData.length = 0;
      runOnecode();
    }
    
    function runOnecode() {
      var str  = "";
      str += $(".google-visualization-controls-rangefilter-thumblabel").text();
      var until = str.substring(10);
      var from = str.substring(0,10);
      var center = $("#centerSelect option:selected").text();
      var query = [
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND G =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND H =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND I =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND J =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND K =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND N =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND O =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND P =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND Q =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND R =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND S =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND T =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND U =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND V =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND W =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND X =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND Y =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND Z =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND AA =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND AB =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND AC =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND AD =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND AE =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND AF =\"No\" "),
        ("SELECT COUNT(A) WHERE C =\"" + center + "\" AND todate(A)  >=date \'" + from + "\' AND todate(A)  <=date \'" + until + "\' AND AG =\"No\" ")
      ];
    
      getData(query[i]);
    }
    </script>
    <script>
    function getData(incomingQuery) {
    
      // Prepare the query 
      var queryString = encodeURIComponent(incomingQuery);
      var query = new google.visualization.Query(
        //Collect the data from this spreadsheet
      'MySpreadSheet URL' + queryString);
      query.send(handleSampleDataQueryResponse);
    
      //Handle any errors from the Google server
      function handleSampleDataQueryResponse(response) {
        if (response.isError()) {
          alert('Error in query: ' + response.getMessage() + ' ' +
            response.getDetailedMessage());
          return;
        }
    
        // get look into the resulting data and find the detail.     
        var datas = response.getDataTable();
        if (datas.Gf.length === 0) {
          resultData = 0;
        } else resultData = datas.Gf[0].c[0].v;
    
        allData.push(resultData);
        //     console.log(allData);
    
        if (i < 25) {
          runOnecode();
    
        } else {
          drawTable();
        }
        i++;
      }
    
    }
    </script>
    

1 个答案:

答案 0 :(得分:2)

使用promises,你可以这样做

function runOnecode() {
    var str  = "";
    str += $(".google-visualization-controls-rangefilter-thumblabel").text();
    var until = str.substring(10);
    var from = str.substring(0,10);
    var center = $("#centerSelect option:selected").text();
    var query = [
        // your query data, removed for brevity ...
    ];
    Promise.all(query.map(getData))
    .then(function(results) {
        // results is an array of results in the same order as query
    })
    .catch(function(err) {
        // err is FIRST error - no other information about success/faill of other queries will be available
    });
}

function getData(incomingQuery) {
    return new Promise(function(fulfill, reject) {
        // Prepare the query 
        var queryString = encodeURIComponent(incomingQuery);
        var query = new google.visualization.Query(
            //Collect the data from this spreadsheet
            'MySpreadSheet URL' + queryString);
        query.send(handleSampleDataQueryResponse);

        //Handle any errors from the Google server
        function handleSampleDataQueryResponse(response) {
            if (response.isError()) {
                throw('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
            }

            // get look into the resulting data and find the detail.     
            var datas = response.getDataTable();
            console.log(datas);
            if (datas.Gf.length === 0) {
                resultData = 0;
            } else {
                resultData = datas.Gf[0].c[0].v;
            }
            fulfill(resultData);
        }
    });
}

如果你需要获得所有查询成功/失败的状态,你可以使用像Q promises这样的东西,它有一个allSettled方法(而不是Promise.all),它返回所有promises的结果,无论成功/失败< / p>

或者,这是我自己推出的一个

Promise.allSettled = function(arr) { 
    return Promise.all([].map.call(arr, 
        function(v) {
            return Promise.resolve(v).then(
                function fulfilled (x) { return {fulfilled: true,  value: x}; }, 
                function rejected  (e) { return {fulfilled: false, value: e}; }
            );
        })
    );
};
然后

runOnecode看起来像

function runOnecode() {
    var str  = "";
    str += $(".google-visualization-controls-rangefilter-thumblabel").text();
    var until = str.substring(10);
    var from = str.substring(0,10);
    var center = $("#centerSelect option:selected").text();
    var query = [
        // your query data, removed for brevity ...
    ];
    Promise.allSettled(query.map(getData))
    .then(function(results) {
        // results is an array of results in the same order as query
        results.forEach(function(result) {
            if (result.fulfilled) {
                // successful
                console.log(result.value);
            }
            else {
                // unsuccessful
                console.log(result.value); // will show the thrown error
            }
        });
    });
}