Caching 阻止自定义函数在Google电子表格Google Apps脚本中执行
编写要在电子表格单元格中使用的自定义函数时,工作表的默认行为是在编辑时重新计算,即添加列或行将导致自定义函数更新 这是一个问题,如果自定义函数调用付费API并使用积分,用户将自动使用API积分 我想不出防止这种情况发生的方法,所以我决定使用缓存将结果缓存任意25分钟,并在用户碰巧重复相同的函数调用时将结果返回给用户。它肯定不是防弹的,但我想总比没有好。很明显是正确的,但这是正确的方法吗?我能做些更聪明的事吗Caching 阻止自定义函数在Google电子表格Google Apps脚本中执行,caching,google-apps-script,google-sheets,custom-function,Caching,Google Apps Script,Google Sheets,Custom Function,编写要在电子表格单元格中使用的自定义函数时,工作表的默认行为是在编辑时重新计算,即添加列或行将导致自定义函数更新 这是一个问题,如果自定义函数调用付费API并使用积分,用户将自动使用API积分 我想不出防止这种情况发生的方法,所以我决定使用缓存将结果缓存任意25分钟,并在用户碰巧重复相同的函数调用时将结果返回给用户。它肯定不是防弹的,但我想总比没有好。很明显是正确的,但这是正确的方法吗?我能做些更聪明的事吗 var _ROOT = { cache : CacheService.getU
var _ROOT = {
cache : CacheService.getUserCache(),
cacheDefaultTime: 1500,
// Step 1 -- Construct a unique name for function call storage using the
// function name and arguments passed to the function
// example: function getPaidApi(1,2,3) becomes "getPaidApi123"
stringifyFunctionArguments : function(functionName,argumentsPassed) {
var argstring = ''
for (var i = 0; i < argumentsPassed.length; i++) {
argstring += argumentsPassed[i]
}
return functionName+argstring
},
//Step 2 -- when a user calls a function that uses a paid api, we want to
//cache the results for 25 minutes
addToCache : function (encoded, returnedValues) {
var values = {
returnValues : returnedValues
}
Logger.log(encoded)
this.cache.put(encoded, JSON.stringify(values), this.cacheDefaultTime)
}
//Step 3 -- if the user repeats the exact same function call with the same
//arguments, we give them the cached result
//this way, we don't consume API credits as easily.
checkCache : function(encoded) {
var cached = this.cache.get(encoded);
try {
cached = JSON.parse(cached)
return cached.returnValues
} catch (e) {
return false;
}
}
}
GoogleSheets已经缓存了自定义函数的值,并且只有当a函数的输入发生变化或者b电子表格在关闭很长时间后被打开时,才会再次运行它们。我无法复制您在添加和删除列时提到的重新计算。下面是我用来测试的一个简单示例函数:
function rng() {
return Math.random();
}
对于昂贵的查询,您使用额外缓存的方法通常看起来不错。我建议使用DocumentCache而不是UserCache,因为文档的所有用户都可以并且应该看到相同的单元格值
我还建议对函数签名进行更健壮的编码,因为您当前的实现能够区分参数[1,2]和[12]。您可以将输入字符串化,然后对其进行base64编码以实现紧凑性:
function encode(functionName, argumentsPassed) {
var data = [functionName].concat(argumentsPassed);
var json = JSON.stringify(data);
return Utilities.base64Encode(json);
}
下面是添加新列或行时自定义函数更新的视频。如果函数接受单元格引用作为参数,并且该单元格在添加列或行时被移动,则自定义函数将更新。此外,如果包含自定义函数的单元格中添加了行/列,则该单元格也会更新。理想情况下,我会阻止自定义功能的更新。YouTube不会加载视频,说它不可用。你能检查一下ACL吗?应该可以,只是再次将其更改为未列出。。谢谢你在这里花时间。