google-apps-script - 如何在避免权限错误的同时使用全局变量?
问题描述
请参见下面的示例,
function doSomething1(){/*needs ss*/const ss = SpreadsheetApp.openById(/*SPREADSHEET_ID*/);}
function doSomething2(){/*needs ss*/const ss = SpreadsheetApp.openById(/*SPREADSHEET_ID*/);}
function doItAll(){
doSomething1();
doSomething2();
}
而不是在这两个函数中调用电子表格,这可以使用全局变量简化为
const ss = SpreadsheetApp.openById(/*SPREADSHEET_ID*/);
function doSomething1(){/*do something with ss*/}
function doSomething2(){/*do something with ss*/}
function doItAll(){
doSomething1();
doSomething2();
}
这里的问题可以在不使用全局变量的情况下通过简单地ss
在函数之间传递变量来解决。ss
但是,对于需要访问变量的多个函数,这将变得更加复杂。而且传球ss
很麻烦。没有很多方法可以避免 Apps 脚本中的全局变量。不支持模块。如果您使用 IIFE,则所有函数都对 IDE 隐藏 - 从 IDE 或其他任何地方调用函数是不可能的。在这里使用全局变量要优雅得多。但是如果我有一个简单的触发器,就会出现问题:
const ss = SpreadsheetApp.openById(/*SPREADSHEET_ID*/);
function doSomething1(){/*do something with ss*/}
function doSomething2(){/*do something with ss*/}
function doItAll(){
doSomething1();
doSomething2();
}
function onOpen(){/*Adds a menu*/}
菜单添加将失败,因为此行之前onOpen
已加载,并且该行需要权限/授权,而作为简单触发器不会运行任何需要授权的代码。SpreadsheetApp.openById(/*SPREADSHEET_ID*/)
onOpen
onOpen
如何在不遇到授权错误的情况下声明全局变量?
解决方案
这个问题可以通过使用getter来解决。getter 仅在从任何地方调用时才执行代码,从而将代码的执行封装在全局上下文中。但是 getter 将在每次调用变量时执行。如果ss
在两个函数中调用,SpreadsheetApp.openById
则执行两次。我们可以使用MDN 中提到的延迟加载技术来避免这种情况。
const config = {
get ss() {
delete this.ss;
return (this.ss = SpreadsheetApp.openById(/*SPREADSHEET_ID*/));
},
};
function doSomething1(){/*do something with config.ss*/}
function doSomething2(){/*do something with config.ss*/}
function doItAll(){
doSomething1();
doSomething2();
}
function onOpen(){/*Adds a menu*/}
在这里,我们在对象内部使用getter,而不是直接声明ss
. 以这种方式使用,SpreadsheetApp.openById()
永远不会在全局范围内调用,尽管它是在全局范围内声明的。它仅在doSomething1
执行时加载。此外,从 访问该方法时不会再次调用该方法doSomething2
,因为 getter 在第一次访问时被删除并替换为实际值。
虽然代码变得有点笨重,但这解决了很多问题并且更加优雅。
样品:
推荐阅读
- python - 在数据框中搜索确切的元组/列表/系列
- javascript - 如何忽略 TypeScript 装饰器(使用 NestJS 实体,如常用类型)?
- php - codeigniter中的MLM树结构
- c++ - 如何比较以下两个对象?
- javascript - 带有 JQuery 的禁用字段出现在 C# 服务器端的请求中
- vb.net - form.show 上的 TypeInitializationException,它曾经在那里工作
- http - 用于分布式抓取解决方案负载平衡的高级 HTTP/2 代理
- html - 如何在输入中使用模式来强制它不接受“-”?
- checkbox - 如果选中复选框,则使用脚本从 Google Sheet 中的行生成文档
- tomcat - 如何在启动时查看传递给 tomcat8 的选项?