Google Apps Script多次触发场景下如何持久化存储数组值?
问题原因
Google Apps Script 每次触发器执行时都会创建全新的运行上下文:全局变量x仅在单次触发的运行周期内存在,触发结束后内存就会被回收,下一次触发重新执行脚本时,x会被重新初始化为空数组,自然无法保留之前写入的数据。
解决思路
你已经用PropertiesService存储了循环的起始位置,只需要把数组也通过PropertiesService持久化存储即可,由于PropertiesService仅支持存储字符串类型,需要用JSON做序列化/反序列化转换。
修改后的完整代码
function main () { var startTime = new Date().getTime(); var scriptProperties = PropertiesService.getScriptProperties(); // 读取上一次存储的起始位置,第一次运行没有值的话默认从0开始 var start = parseInt(scriptProperties.getProperty('start')) || 0; // 读取上一次存储的数组,第一次运行没有值的话默认是空数组 var x = JSON.parse(scriptProperties.getProperty('dataArray') || '[]'); for (var i = start ; i <= 1000; i++) { var currentTime = new Date().getTime(); if (currentTime - startTime >= 250000) { // 退出前保存当前进度和数组数据 scriptProperties.setProperty('start', i); scriptProperties.setProperty('dataArray', JSON.stringify(x)); // 先删除已有的同函数触发器,避免触发器数量超限 deleteExistingTriggers('main'); ScriptApp.newTrigger('main') .timeBased() .after(5 * 60 * 1000) // 按需求设置5分钟间隔 .create(); return; // 直接退出当前执行 } else { x.push(i); } } // 全部执行完成的逻辑 Logger.log('return values of array x ' + x); // 执行完成后清理不需要的存储和触发器 scriptProperties.deleteProperty('start'); scriptProperties.deleteProperty('dataArray'); deleteExistingTriggers('main'); } // 工具函数:删除指定函数的所有已存在触发器 function deleteExistingTriggers(functionName) { var allTriggers = ScriptApp.getProjectTriggers(); for (var i = 0; i < allTriggers.length; i++) { if (allTriggers[i].getHandlerFunction() === functionName) { ScriptApp.deleteTrigger(allTriggers[i]); } } }
注意事项
- 如果你的数组数据量非常大,超出了
PropertiesService单条属性9KB的存储上限,可以改用 Google Sheets 或者 Drive 文本文件存储数组数据 - 触发器累计数量有配额限制,所以每次创建新触发器前先删除旧的同函数触发器,避免触发配额报错
内容的提问来源于stack exchange,提问作者Minh Dao
相关产品推荐
相关产品推荐

