时钟触发器构建器在调度时不调用函数 - Google Sheet app脚本

时间:2015-07-31 15:19:57

标签: google-apps-script google-sheets google-prediction

我正在使用Google提供的应用脚本通过工作表访问他们的预测API。我试图一次预测数千行,但是,在6分钟后,代码停止时达到最大执行时间。

我实现了一个使用时钟触发器构建器找到的解决方案。一旦我运行该功能它会持续5分钟,然后停止设置触发器以在2分钟内调用该功能。

主要问题是在安排时不调用该函数。我在当前触发器列表中看到它,但它永远不会被再次调用。你能解释一下为什么会这样吗。

我的目的是在5分钟内预测尽可能多的行,然后停止设置触发器,在几分钟内从中断处开始再次调用预测函数,并继续直到预测到任何元素。

我还需要知道如何将值存储在缓存中,以便在再次调用该函数时知道它所需的所有信息。

//This is the function that is used to predict a selection of data
function predict() {
  try {
    clearOutput();
    var startTime= (new Date()).getTime();
    var sheet = SpreadsheetApp.getActiveSheet();
    var selection = sheet.getActiveSelection();
    var instances = selection.getValues();
    var project_number = getProjectNumber();
    var model_name = getModelName();
    var startRow = stRow; 
    var MAX_RUNNING_TIME = 300000;
    var REASONABLE_TIME_TO_WAIT = 60000;
    for (var i = startRow; i < instances.length; ++i) {
      var currTime = (new Date()).getTime();
      if(currTime - startTime >= MAX_RUNNING_TIME) {
        var builder = ScriptApp.newTrigger('predict').timeBased().after(REASONABLE_TIME_TO_WAIT);
    builder.create();
    break;
  } else {  
    var result = predictSingleRow(project_number, model_name, instances[i]);
    selection.getCell(i + 1, 1).setValue(result);
  }
    }
  } catch(e) {
    Browser.msgBox('ERROR:' + e, Browser.Buttons.OK);
  }
}

1 个答案:

答案 0 :(得分:0)

为什么您的代码无法按预期运行,很少有事情:

1)既然你提到了“我在当前触发器列表中看到它,但它永远不会被再次调用”并查看你的代码,我不确定你是否打算在执行完成后再次调用该函数。如果这样做,这是因为您的for循环运行了一段时间,直到获得instances的长度。脚本中没有任何内容表明函数需要在完成迭代instances后再次运行。请参阅此链接,了解如何Manage Trigger Programmatically

2)var builder = ScriptApp.newTrigger('predict').timeBased().after(REASONABLE_TIME_TO_WAIT);

这段代码属于if条件,停止执行1分钟(值为60000)。因此,在执行开始后添加1分钟。无法将startTime计数器重置为等待时间之后的时间,因为一旦currTime - startTime的值超过MAX_RUNNING_TIME,该函数将继续为所有人调用if循环之后for循环的迭代。简单地说,如果startTime是9:35且currTime是9:40,等待1分钟后currTime是9:41,这仍然超过MAX_RUNNING_TIME (5分钟)因为startTime的值仍然是9:35。此时将其重置为9:41可以解决您的问题。

3)松开break循环中的if可能也有助于解决这个问题。

修改

添加一个功能,如上面提到的链接所示:

function callTrigger(){
  ScriptApp.newTrigger('predict')
      .timeBased()
      .everyMinutes(30)
      .create();
}

从编辑器运行一次函数callTrigger,你应该好好去。请记住,几分钟您只能传递值1,5,15或30。