【问题标题】:Google App Script Trigger Id FormatGoogle 应用脚本触发器 ID 格式
【发布时间】:2016-08-20 17:58:48
【问题描述】:

我正在处理 Google 电子表格的项目,我正在通过脚本添加/删除基于时间的触发器。

所有触发的触发器将运行一个函数,该函数将检查其 Id 并相应地运行函数。

我正在保存启动触发器并使用此代码保存它的 id。

function startTimer(rn) {
  var triggerid = ScriptApp.newTrigger('mainFunction')
      .timeBased()
      .everyMinutes(1)
      .create().getUniqueId();

  SpreadsheetApp.getActiveSheet().getRange(1, 8).setValue(triggerid);
}

此函数以“6295890543675972447”格式保存触发器ID

现在当触发器被触发并运行函数“mainFunction”时。 使用此代码,我正在尝试获取触发器的 ID。

function mainFunction(e) {
  var triggerId = e.triggerUid;
  Logger.log(triggerId);
}

此时,我得到了这种格式的触发器 id '6.29589E+18'
如果我尝试使用 toString() 方法更改格式,格式将更改为 '6295890543675973000'

我无法将两种格式都匹配到我保存的 id。

知道如何以添加触发器时的格式恢复 id 吗?


谢谢

【问题讨论】:

    标签: javascript google-apps-script google-apps


    【解决方案1】:

    我在这上面花了几个小时,弄掉了一些头发。 我找到了this page。当您在其中传递 e.triggerUid 时,它有一段奇怪的代码,而不是直接使用它时:

    function getFileByTriggerId(triggerId){
      var triggers = ScriptApp.getProjectTriggers();
      for(var i =0; i<triggers.length; i++){
        if(triggers[i].getUniqueId() == triggerId){
          return triggers[i].getTriggerSourceId();
        }
      }
    }
    

    希望对大家有所帮助

    【讨论】:

      【解决方案2】:

      当您使用其getUniqueId() 方法请求触发器对象的ID 时,返回的值是一个数字String

      但是,当触发器调用函数时,事件对象的triggerUid 属性将是转换为数字的字符串。

      问题在于字符串 id经常(但不总是)表示一个大于 Apps 脚本可以安全处理的最大整数值的整数值。发生这种情况时,从字符串到数字的转换会导致最低有效数字为零。

      因此,要正确比较两者,您只需将字符串 id 转换为数字,这样可以确保发生相同的归零。

      someTrigger.getUniqueId() === event.triggerUid
      // false - because the left side is a string, and the right is a number. 
      
      Number(someTrigger.getUniqueId()) === event.triggerUid
      // true - both sides are now numbers, the same number
      
      someTrigger.getUniqueId() == event.triggerUid
      // true - because using the standard comparison operator the string is automatically converted to a number in the background
      

      这是a note 关于严格与Javascript 中的标准比较操作。

      这里有一些演示上述所有内容的 Apps 脚本:

      // Run onceOffClockTimer() and wait up to 1 min for the event to fire, then check your log. You might have to run it a few times to see a trigger id where the zeroing occurred
      
      function onceOffClockTimer() {
        var newTriggerId = ScriptApp.newTrigger('timerCallbackFn')
          .timeBased()
          .after(5000)
          .create()
          .getUniqueId();
      }
      
      
      function timerCallbackFn(triggerEvent) {
      
        var eventTriggerId = triggerEvent.triggerUid,
          triggers = ScriptApp.getProjectTriggers();
        Logger
          .log('### Event Object ###')
          .log('id: %s', eventTriggerId)
          .log('id type: %s', typeof eventTriggerId)
          .log('id as String: %s\n', eventTriggerId.toString());
      
        var largestSafeInteger = 9007199254740991; // Obtained by Number.MAX_SAFE_INTEGER in a Chrome console 
      
        Logger
          .log('### Interesting Fact ###')
          .log('In Apps Script the largest safe integer is: %s\n', largestSafeInteger);
      
        for (var i = 0, x = triggers.length; i < x; i++) {
      
          var triggerID = triggers[i].getUniqueId();
      
          Logger
            .log('### Trigger Object [%s] ###', i)
            .log('id: %s', triggerID)
            .log('id type: %s', typeof triggerID)
            .log('id as Number: %s\n', Number(triggerID))
      
          Logger
            .log('### Comparisons ###')
            .log('Strict (Trigger Event ID === Trigger ID) is %s ', eventTriggerId === triggerID)
            .log('Strict (Trigger Event ID === Trigger ID as Number) is %s', eventTriggerId === Number(triggerID))
            .log('Direct (Trigger Event ID == Trigger ID) is %s', eventTriggerId == triggerID);
        }
      }

      【讨论】:

        【解决方案3】:
        Logger.log('' + triggerId);;;;
        

        【讨论】:

          【解决方案4】:

          触发器 ID 可以是一个大数字(长 8 字节整数,或者存储为对象的更大数字),为了克服这个问题,将其转换为二进制,然后转换为 64 位编码字符串。这样您就可以安全地存储和比较。

          var v = Utilities.base64Encode(Utilities.newBlob(e.triggerUid).getBytes())
          

          或者比较

          if(Utilities.base64Encode(Utilities.newBlob(e.triggerUid).getBytes()) === Utilities.base64Encode(Utilities.newBlob(triggers[i].getUniqueId()).getBytes()))
          

          【讨论】:

            【解决方案5】:

            由于 triggerId 是 Number 对象,因此它会自动转换为指数表示法。

            要处理此问题,您可以扩展 Number.prototype 以处理正确的表示。

            Object.defineProperty(Number.prototype, 'toLongString', {
              value: function() {
                var parts = this.toString().split("e+");
                var first = parts[0].replace('.', "");
                var zeroes = parseInt(parts[1], 10) - (first.length - 1);
            
                var longString = first;
            
                for (var i = 0; i < zeroes; i++) {
                  longString += "0";
                }
            
                return longString;
              }
            });
            
            function mainFunction(e) {
              var triggerId = e.triggerUid.toLongString();
              Logger.log(triggerId);
            }
            

            【讨论】:

              【解决方案6】:

              我遇到了同样的问题。对我有用的解决方案是:toPrecision([numberOfDigits])

              例如:

              ([largenumber]).toPrecision(27)

              以下是来源: https://teamtreehouse.com/community/covert-scientific-notation-within-variable-to-javascript-number-when-scientific-notation-is-yet-unknown

              我希望这对某人有所帮助!

              【讨论】:

                猜你喜欢
                • 2018-03-20
                • 2016-12-08
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多