在 Google apps Script (GAS) 中,跨函数共享变量时,你可能会遇到变量值意外重置的问题。这是因为 GAS 的执行模型将每次函数调用视为一个独立的执行环境。这意味着,即使你在一个函数中修改了全局变量,当另一个函数被调用时,该全局变量会被重新初始化,导致之前所做的修改丢失。
问题根源:GAS 的执行机制
GAS 的执行机制是解决此问题的关键。当你的 Google Workspace 插件(例如 Google Calendar 插件)运行时,每个用户界面交互(例如点击按钮)都会触发一个单独的脚本执行。这意味着,即使你在 createCard() 函数中将 startdate 设置为 “tomorrow”,当用户点击按钮并调用 reviseStartDate() 函数时,脚本会重新执行,startdate 变量会被重新初始化为 “today”。
解决方案:使用 CacheService 或 User Properties
为了在不同的函数调用之间保持变量的状态,我们需要使用一种机制来持久化变量的值。GAS 提供了两种常用的方法:CacheService 和 User Properties。
使用 CacheService
CacheService 允许你将数据存储在缓存中,并在不同的函数调用之间共享这些数据。以下是如何使用 CacheService 修改你的代码:
var cache = CacheService.getUserCache(); function onHomepage() { var card = createCard(); return card; } function createCard() { cache.put("startdate", "tomorrow"); // 将 startdate 存储在缓存中 var startdate = cache.get("startdate"); // 从缓存中获取 startdate var button = CardService.newTextButton() .setText('Revise start date') .setOnClickAction(CardService.newAction() .setFunctionName('reviseStartDate')); var section = CardService.newCardSection() .addWidget(button); var card = CardService.newCardBuilder() .setHeader(CardService.newCardHeader().setTitle('Default start: ' + startdate)) .addSection(section) return card.build(); } function reviseStartDate() { var startdate = cache.get("startdate"); // 从缓存中获取 startdate var card = CardService.newCardBuilder() .setHeader(CardService.newCardHeader().setTitle("Revised start: " + startdate)); return card.build(); }
代码解释:
- 获取缓存: CacheService.getUserCache() 获取与当前用户关联的缓存。
- 存储数据: cache.put(“startdate”, “tomorrow”) 将键 “startdate” 的值设置为 “tomorrow” 并存储在缓存中。
- 检索数据: cache.get(“startdate”) 从缓存中检索键 “startdate” 的值。
通过使用 CacheService,我们确保 startdate 的值在 createCard() 函数中被设置为 “tomorrow”,并且在 reviseStartDate() 函数中能够正确地检索到该值。
使用 User Properties
User Properties 类似于 CacheService,但它提供了一种更持久的存储机制。User Properties 将数据存储在用户的 Google 帐户中,这意味着即使脚本重新部署,数据仍然可用。
以下是如何使用 User Properties 修改你的代码:
var userProperties = PropertiesService.getUserProperties(); function onHomepage() { var card = createCard(); return card; } function createCard() { userProperties.setProperty("startdate", "tomorrow"); // 将 startdate 存储在 User Properties 中 var startdate = userProperties.getProperty("startdate"); // 从 User Properties 中获取 startdate var button = CardService.newTextButton() .setText('Revise start date') .setOnClickAction(CardService.newAction() .setFunctionName('reviseStartDate')); var section = CardService.newCardSection() .addWidget(button); var card = CardService.newCardBuilder() .setHeader(CardService.newCardHeader().setTitle('Default start: ' + startdate)) .addSection(section) return card.build(); } function reviseStartDate() { var startdate = userProperties.getProperty("startdate"); // 从 User Properties 中获取 startdate var card = CardService.newCardBuilder() .setHeader(CardService.newCardHeader().setTitle("Revised start: " + startdate)); return card.build(); }
代码解释:
- 获取 User Properties: PropertiesService.getUserProperties() 获取与当前用户关联的 User Properties。
- 存储数据: userProperties.setProperty(“startdate”, “tomorrow”) 将键 “startdate” 的值设置为 “tomorrow” 并存储在 User Properties 中。
- 检索数据: userProperties.getProperty(“startdate”) 从 User Properties 中检索键 “startdate” 的值。
注意事项:
- CacheService 的数据可能会在一段时间后过期,而 User Properties 的数据则会更持久。 选择哪种方法取决于你的具体需求。 如果你需要临时存储数据,可以使用 CacheService。 如果你需要永久存储数据,可以使用 User Properties。
- CacheService 和 User Properties 都有存储容量限制。 请确保你的数据量不超过这些限制。
- 在生产环境中,建议对存储在 CacheService 和 User Properties 中的敏感数据进行加密。
总结
在 Google Apps Script 中跨函数共享变量需要特别注意 GAS 的执行机制。通过使用 CacheService 或 User Properties,你可以有效地持久化变量的值,确保它们在不同的函数调用之间保持一致。选择哪种方法取决于你的具体需求,但理解这些概念对于构建健壮的 Google Workspace 插件至关重要。