【问题标题】:Using promises for mulitple queries to Google sheets使用 Promise 对 Google 表格进行多次查询
【发布时间】:2016-02-09 05:22:21
【问题描述】:

我是一名初学者,希望获得一些帮助以加快我的 Google 表格查询速度。我环顾四周,找不到解决方案。我正在尝试快速对 Google 工作表运行 25 个查询,这就是我正在尝试的方式:

  1. 对 Google 工作表运行查询。
  2. 将结果推送到数组。
  3. 运行不同的查询。
  4. 将结果推送到同一个数组。
  5. 运行下一个查询... x 25。
  6. 绘制最终结果表格。

问题是,如果我逐个运行查询,它们需要 25 秒才能完成。如果我在 for 循环中运行查询,结果会在 2 秒内返回,但是是异步的,并且数据完全不正常。也许,我应该使用一个承诺,或者别的什么。请你帮忙。

这里是慢版本的代码:

   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>

这是异步返回结果的快速版本:

<script>
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\" ")
  ];
for(var i=0; i<25; i++){
  getData(query[i]);
// When all are done I will draw the table. 

}
}
</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();
    console.log(datas);
    if (datas.Gf.length === 0) {
      resultData = 0;
    } else resultData = datas.Gf[0].c[0].v;

    allData.push(resultData);
      console.log(allData);
  }

}
</script>

【问题讨论】:

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


    【解决方案1】:

    使用承诺,你可以做到这一点

    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 的结果而不管成功/失败

    或者,这是我自己卷的一个

    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
                }
            });
        });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多