【问题标题】:Google Apps Script web-app not running asynchronously as expectedGoogle Apps 脚本网络应用程序未按预期异步运行
【发布时间】:2021-01-13 13:05:24
【问题描述】:

我有一个非阻塞(即没有 LockService)网络应用程序,它返回一个存储在 ScriptProperties 中的计数器。

我在脚本中有一个人工睡眠来测试对网络应用的异步调用。

看看下面的这段代码,我假设对网络应用程序的两次连续调用应该返回相同的数字。

但是,事实并非如此。对网络应用程序的两次调用,一个接一个,返回越来越多的数字。这让我觉得第一个调用在第二个调用之前完成——这没有意义。

function doGet(e)
{
    // get script properties
    var scriptProperties = PropertiesService.getScriptProperties();
    
    // get ID
    var id = parseInt(scriptProperties.getProperty("id"));

    // fake a long process
    // enough time to make another call to the web-app
    // in theory, the second call will get the same value for `id`
    Utilities.sleep(5000);

    // write a new value
    scriptProperties.setProperty("id", id + 1);
    
    // return it
    return ContentService.createTextOutput(id);
}

我试图弄清楚如何/为什么。 Google 不支持网络应用的异步调用吗?

你可以在https://script.google.com/macros/s/AKfycbxP6TQeMv_4b1lsYvGLA3YAn_reBhZ64Y2d04DotQ4CFJQtKhM/exec看到这个运行。

** 更新 **

这是我用来测试的本地 HTML 文件。

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script type="text/javascript">
        function doIt()
        {
            console.log("doIt: start");
            setTimeout(callIt, 500);
            console.log("doIt: end");
        }

        function callIt()
        {
            console.log("callIt: start");
            var request = new XMLHttpRequest();
            request.open('GET', 'https://script.google.com/macros/s/AKfycbxP6TQeMv_4b1lsYvGLA3YAn_reBhZ64Y2d04DotQ4CFJQtKhM/exec', true);

            request.onload = function()
            {
                if(this.status >= 200 && this.status < 400)
                {
                    document.querySelector("#output").innerText += this.response + ", ";
                }
                else
                {
                    alert("error");
                }
            };

            request.onerror = function()
            {
                alert("error");
            };

            request.send();
            console.log("callIt: end");
        }
    </script>
  </head>
  <body>
    output:
    <div id="output"></div>
    <input type="button" value="Click me" onclick="doIt()">
  </body>
</html>

快速单击按钮应该返回相同的数字,但它不会...

【问题讨论】:

  • 您能否提供脚本和/或您向 Web 应用程序请求的方法?因为在使用UrlFetchApp.fetchAll([{url: url}, {url: url}])的脚本时,会返回2个相同的值。
  • 我很快就在两个标签中打开了script.google.com/macros/s/…。我什至在我的计算机上尝试了一个本地 HTML 文件。我会用它的来源更新问题。
  • 感谢您的回复。从您的问题和附加脚本中的Does Google not support asynchronous calls for web-apps?,我认为您的问题可能有2个问题。因此,首先,关于您的问题中的Does Google not support asynchronous calls for web-apps?,如何确认?为了检查它,作为简单的脚本,您可以使用UrlFetchApp.fetchAll([{url: url}, {url: url}]).forEach(e =&gt; console.log(e.getContentText())); 的 Google Apps 脚本进行检查。下一步,将考虑您的脚本。这个怎么样?

标签: asynchronous google-apps-script web-applications locking


【解决方案1】:

是的!像 doPost() 这样的 Web 应用程序调用异步运行。

问题:

您无法复制冲突的原因是因为您的 sleep 时间相对于浏览器进行 http 调用所用的时间太短了

解决办法:

  • sleep 增加到 1 分钟或更长时间。

    Utilities.sleep(1*60*1000);
    
  • 如果您使用以下 sn-p 脚本使用随机睡眠时间,您还可以轻松证明异步性,该脚本将显示每个循环的时间以及随机的“callIt end”。

    Utilities.sleep(Math.floor(Math.random()*60000)+1);
    

/*<ignore>*/console.config({maximize:true,timeStamps:false,autoScroll:true});/*</ignore>*/
function callIt(i) {
  const label = 'callIt' + i;
  console.log(label + ' start');
  console.time(label);
  const request = new XMLHttpRequest();
  request.open(
    'GET',
    'https://script.google.com/macros/s/AKfycbxP6TQeMv_4b1lsYvGLA3YAn_reBhZ64Y2d04DotQ4CFJQtKhM/exec',
    true
  );

  request.onload = function() {
    if (this.status >= 200 && this.status < 400) {
      console.log(this.response + `- ${label}`);
      console.log(label + ' end');
      console.timeEnd(label);
      console.log('\n')
    } else {
      alert('error');
    }
  };

  request.onerror = function() {
    alert('error');
  };

  request.send();
}
let i = 0;
while (++i < 10) callIt(i);
&lt;!-- https://meta.stackoverflow.com/a/375985/ --&gt;    &lt;script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"&gt;&lt;/script&gt;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-10
    • 2020-07-26
    • 1970-01-01
    • 2018-06-04
    • 2017-11-06
    • 2019-10-19
    • 2019-04-09
    相关资源
    最近更新 更多