首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Google应用程序脚本超时~5分钟?

Google应用程序脚本超时~5分钟?
EN

Stack Overflow用户
提问于 2013-01-22 10:53:10
回答 12查看 64.4K关注 0票数 35

我的google应用程序脚本正在迭代用户的google驱动器文件,并复制文件,有时还会将文件移动到其他文件夹。脚本始终在5分钟后停止,并且在日志中没有错误消息。

我在一次运行中对数十个甚至数千个文件进行排序。

是否有任何设置或解决方法?

EN

回答 12

Stack Overflow用户

发布于 2011-12-23 02:36:29

您可以做的一件事(这当然取决于您试图完成的任务)是:

  1. 将必要的信息(如循环计数器)存储在电子表格或另一个永久存储区中(即,每五分钟左右终止一次脚本)。
  2. 设置一个时间驱动触发器,以便每五分钟运行一次脚本(或使用Script service).
  3. On以编程方式创建触发器)每次运行从永久存储区读取保存的数据,然后从脚本停止的位置继续运行。

这不是一个放之四海而皆准的解决方案,如果你发布你的代码,人们将能够更好地帮助你。

以下是我每天使用的脚本的简化代码摘录:

代码语言:javascript
复制
function runMe() {
  var startTime= (new Date()).getTime();
  
  //do some work here
  
  var scriptProperties = PropertiesService.getScriptProperties();
  var startRow= scriptProperties.getProperty('start_row');
  for(var ii = startRow; ii <= size; ii++) {
    var currTime = (new Date()).getTime();
    if(currTime - startTime >= MAX_RUNNING_TIME) {
      scriptProperties.setProperty("start_row", ii);
      ScriptApp.newTrigger("runMe")
               .timeBased()
               .at(new Date(currTime+REASONABLE_TIME_TO_WAIT))
               .create();
      break;
    } else {
      doSomeWork();
    }
  }
  
  //do some more work here
  
}

NOTE#1:变量REASONABLE_TIME_TO_WAIT应足够大,以便触发新触发器。(我将其设置为5分钟,但我认为可以少于5分钟)。

NOTE#2:doSomeWork()必须是一个执行相对较快的函数(我想说少于1分钟)。

NOTE#3 :谷歌已经弃用了Script Properties,取而代之的是Properties Service。已对函数进行了相应修改。

NOTE#4:第二次调用函数时,取for循环的第i个值作为字符串。所以你必须把它转换成一个整数

票数 88
EN

Stack Overflow用户

发布于 2015-04-22 22:29:19

配额

execution

单个脚本的最大执行时间为6分钟/

但要熟悉它还有其他限制。例如,您只允许1小时/天的总触发器运行时间,因此您不能将一个长函数分解为12个不同的5分钟块。

优化

也就是说,没有什么理由能解释为什么你真的需要花6分钟来执行。JavaScript在几秒钟内对数千行数据进行排序应该没有问题。可能会影响性能的是对Google Apps本身的服务调用。

您可以编写脚本,通过最小化读写次数来最大限度地利用内置缓存。交替的读取和写入命令速度很慢。要加快脚本速度,请使用一个命令将所有数据读入阵列,对阵列中的数据执行任何操作,然后使用一个command.

将数据写出

批处理

你能做的最好的事情就是减少服务调用的数量。Google通过允许大多数API调用的批处理版本来实现这一点。

举个简单的例子,用代替这个

代码语言:javascript
复制
for (var i = 1; i <= 100; i++) {
  SpreadsheetApp.getActiveSheet().deleteRow(i);
}

执行此操作

代码语言:javascript
复制
SpreadsheetApp.getActiveSheet().deleteRows(i, 100);

在第一个循环中,您不仅需要在工作表上调用100次deleteRow,而且还需要获得100次活动工作表。第二个变种的性能应该比第一个好几个数量级。

交织读和写

此外,你还应该非常小心,不要在读和写之间频繁地来回切换。您不仅会失去批处理操作的潜在收益,而且Google将无法使用其内置缓存。

每次进行读操作时,我们必须首先清空(提交)写缓存,以确保您正在读取最新的数据(您可以通过调用SpreadsheetApp.flush()强制写缓存)。同样,每次执行写操作时,我们都必须丢弃读缓存,因为它不再有效。因此,如果您可以避免读写交错,您将获得cache.

  • http://googleappsscript.blogspot.com/2010/06/optimizing-spreadsheet-operations.html

的全部好处

例如,而不是这个

代码语言:javascript
复制
sheet.getRange("A1").setValue(1);
sheet.getRange("B1").setValue(2);
sheet.getRange("C1").setValue(3);
sheet.getRange("D1").setValue(4);

执行此操作

代码语言:javascript
复制
sheet.getRange("A1:D1").setValues([[1,2,3,4]]);

链接函数调用

作为最后的手段,如果你的函数真的不能在六分钟内完成,你可以将调用链接在一起,或者分解你的函数来处理较小的数据段。

您可以将数据存储在Cache Service (临时)或Properties Service (永久)存储桶中,以便跨执行检索(因为Google Apps Scripts具有无状态执行)。

如果您想要启动另一个事件,您可以使用Trigger Builder Class创建自己的触发器,或者在紧凑的时间表上设置重复触发器。

票数 61
EN

Stack Overflow用户

发布于 2012-01-03 00:28:13

另外,尽量减少对google服务的调用次数。例如,如果您想要更改电子表格中的某个单元格范围,请不要逐个读取,而是对其进行变异并将其存储回去。取而代之的是将整个范围(使用Range.getValues())读取到内存中,对其进行变异并一次性存储(使用Range.setValues())。

这应该会为您节省大量的执行时间。

票数 31
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14450819

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档