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

Mar*_* V. 23 google-apps-script google-drive-api

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

我在一次运行中排序数十或有时数千个文件.

有任何设置或解决方法吗?

Kyl*_*Mit 44

配额

单个脚本的最长执行时间为6分钟/执行
- https://developers.google.com/apps-script/guides/services/quotas

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

优化

也就是说,为什么你真的需要花6分钟才能执行,因此很少有理由.JavaScript在几秒钟内排序数千行数据应该没有问题.对您的性能造成的影响可能是对Google Apps本身的服务调用.

您可以通过最小化读写次数来编写脚本以最大限度地利用内置缓存.交替读写命令很慢.要加速脚本,使用一个命令将所有数据读入数组,对数组中的数据执行任何操作,并使用一个命令写出数据.
- https://developers.google.com/apps-script/best_practices

配料

您可以做的最好的事情是减少服务呼叫的数量.Google通过允许大多数API调用的批量版本来实现此目的.

作为一个简单的例子,而不是这个:

for (var i = 1; i <= 100; i++) {
  SpreadsheetApp.getActiveSheet().deleteRow(i);
}
Run Code Online (Sandbox Code Playgroud)

这样做:

SpreadsheetApp.getActiveSheet().deleteRows(i, 100);
Run Code Online (Sandbox Code Playgroud)

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

交织读写

此外,您还应该非常小心,不要经常在阅读和写作之间来回走动.您不仅会在批处理操作中失去潜在的收益,而且Google将无法使用其内置缓存.

每次执行读取时,我们必须首先清空(提交)写入缓存以确保您正在读取最新数据(您可以通过调用强制写入缓存SpreadsheetApp.flush()).同样,每次执行写操作时,我们都必须丢弃读缓存,因为它不再有效.因此,如果您可以避免交错读取和写入,您将获得缓存的全部好处.
- http://googleappsscript.blogspot.com/2010/06/optimizing-spreadsheet-operations.html

例如,而不是这样:

sheet.getRange("A1").setValue(1);
sheet.getRange("B1").setValue(2);
sheet.getRange("C1").setValue(3);
sheet.getRange("D1").setValue(4);
Run Code Online (Sandbox Code Playgroud)

这样做:

sheet.getRange("A1:D1").setValues([[1,2,3,4]]);
Run Code Online (Sandbox Code Playgroud)

链接函数调用

作为最后的手段,如果您的功能在六分钟内无法完成,您可以将呼叫链接在一起或分解您的功能以处理较小的数据段.

您可以将数据存储在缓存服务(临时)或属性服务(永久)存储桶中,以便跨执行检索(因为Google Apps脚本具有无状态执行).

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

  • *“也就是说,您真的需要花六分钟来执行的原因很少。”* 尝试编写一个脚本来处理 Gmail、Drive 等中的内容... (2认同)

Fre*_*red 11

找出一种分割工作的方法,因为它只需不到6分钟,因为这是任何脚本的限制.在第一遍中,您可以在电子表格中迭代并存储文件和文件夹列表,并为第2部分添加时间驱动的触发器.

在第2部分中,在处理列表时删除列表中的每个条目.如果列表中没有项目,请删除触发器.

这就是我处理一张大约1500行的表格,这些表格可以传播到十几种不同的电子表格中.由于对电子表格的调用次数,它会超时,但会在触发器再次运行时继续.