【问题标题】:How to Implement LockService in Google App Script The Right Way?如何以正确的方式在 Google App 脚本中实现 LockService?
【发布时间】:2021-12-23 07:13:03
【问题描述】:

目前,我正在尝试使用 Google App Script 中的 lockservice 来处理我的 webapp 上的并发性。但是,当我实现它时,它不起作用。

我的网络应用程序的描述:

当用户点击该按钮时,它会在 google sheet 中获取网站地址值并打开一个新窗口以访问该网站。然后,它将用新网站地址的值更新我的谷歌表中的值。

在这个 webapp 上,它将循环浏览 3 个网站 Google -> Youtube -> Facebook

问题:

当我尝试通过快速单击按钮来测试它的并发性时,它会返回相同的网站。例如,如果我点击了两次,它将打开 Google 的 2 个新窗口,但 google sheet 中的值将更新为 Facebook,从而跳过 >YouTube

我试过实现lockservice,但是没用,可能是我实现错了。

这是我的 HTML 代码:

    <html>
  <head>
    <base target="_top">
  </head>
  <body>
    <div class="content">
    <h1>Please Click Below</h1>
    <!-- <h2><?=web?>:</h2> -->
    <button class="button" id = "btn" type="submit" >Open Window</button>
    </div>        
  <script>
  document.getElementById("btn").addEventListener("click", doStuff);
  var web = "";

  function doStuff() {
        google.script.run.withSuccessHandler(openWebsite).getWebsite();
      }

      function openWebsite(web) {
        if (web === "Google") {
          window.open("https://www.google.com/");
        } else if (web === "Youtube") {
          window.open("https://www.youtube.com/");
        } else {
          window.open("https://www.facebook.com/");
        }
        google.script.run.setWebsite();
      }
</script>

  </body>
</html>

我的代码.gs:

    var url = "google sheet url";
var web = "";

function doGet(e) {
 
  let tmp = HtmlService.createTemplateFromFile("index");
  let output = tmp.evaluate().addMetaTag('viewport', 'width=device-width, initial-scale=1');
  return output;

}

function setWebsite () {
  var ss = SpreadsheetApp.openByUrl(url);
  var ws = ss.getSheetByName("website");
  web = ws.getRange(1,1,1,1).getValue();
  var lock = LockService.getScriptLock(); //del
  lock.tryLock(5000); //del
  if (lock.hasLock()) { //del
    if (web === "Google") {
      ws.getRange(1,1,1,1).setValue("Youtube");
    } 
      else if (web === "Youtube") {
      ws.getRange(1,1,1,1).setValue("Facebook");
    }
      else {
      ws.getRange(1,1,1,1).setValue("Google");
    } 

    var xs = ss.getSheetByName("data");
    xs.appendRow([new Date(), web]);
    lock.releaseLock(); //del
    }
  } //del

function getWebsite() {  
  var lock = LockService.getScriptLock();
  lock.tryLock(5000); // wait 5 seconds try to get lock 

  if (lock.hasLock()) {
  var ss = SpreadsheetApp.openByUrl(url);
    var ws = ss.getSheetByName("website");
    var web = ws.getRange(1,1,1,1).getValue();
    lock.releaseLock();
    return web;
    }
  }

// function getWebsite() {  
//   var lock = LockService.getScriptLock();
//   try {
//     lock.waitLock(5000); // wait 5 seconds try to get lock
//   } catch (e) {
//     Logger.log('Could not obtain lock after 5 seconds.');
//   }
//     Utilities.sleep(1000);
//     var ss = SpreadsheetApp.openByUrl(url);
//     var ws = ss.getSheetByName("website");
//     var web = ws.getRange(1,1,1,1).getValue();
//     lock.releaseLock();
//     return web;
//     //lock.releaseLock();
//     }

ps。我尝试了两种不同的方法(在 code.gs 中的评论部分),我可以在 Stackoverflow 和 youtube 上找到它们,但仍然没有成功。

请帮忙。谢谢。

【问题讨论】:

  • 当它被“锁定”时,不会从getWebsite() 返回值,即webundefined。因此,带有window.open("https://www.facebook.com/"); 的块将被执行。请尝试将else 更改为else if (web === "Facebook")
  • 另外,你可能还需要在openWebsite(web)的第一行插入if (!web) { return; },因为你不希望google.script.run.setWebsite();在'锁定'时被执行。

标签: javascript google-apps-script


【解决方案1】:

我认为在您的脚本中,当单击按钮时,google.script.run.withSuccessHandler(openWebsite).getWebsite() 会运行,google.script.run.setWebsite() 也会在函数openWebsite 中运行。在这种情况下,LockService 用于getWebsite()setWebsite() 的每个功能。我认为这可能是您的问题的原因。那么,在您的脚本中,如何进行以下修改?在本次修改中,getWebsite()setWebsite()的功能使用了一个LockService。

HTML&Javascript 端:

请在你的Javascript端修改openWebsite(web)如下。

发件人:

google.script.run.setWebsite();

收件人:

// google.script.run.setWebsite();
  • 在此修改中,google.script.run.setWebsite(); 被删除。

Google Apps 脚本方面:

请在您的 Google Apps 脚本端修改getWebsite(),如下所示。

发件人:

var web = ws.getRange(1,1,1,1).getValue();
lock.releaseLock();

收件人:

var web = ws.getRange(1, 1, 1, 1).getValue();
setWebsite(); // Added
lock.releaseLock();
  • 在此修改中,google.script.run.setWebsite(); 被删除。

注意:

【讨论】:

  • 感谢您回答@Tanaike。我知道我是怎么做错的。我刚刚对其进行了测试,您的解决方案奏效了!再次感谢你。祝你有美好的一天,保持温暖。
  • @ddhalim 感谢您的回复和测试。我很高兴你的问题得到了解决。也谢谢你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-08
  • 2014-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多