The*_*ter 0 lazy-loading global-variables google-sheets 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();
}
Run Code Online (Sandbox Code Playgroud)
可以使用全局变量来简化,而不是在两个函数中调用 Spreadsheet
const ss = SpreadsheetApp.openById(/*SPREADSHEET_ID*/);
function doSomething1(){/*do something with ss*/}
function doSomething2(){/*do something with ss*/}
function doItAll(){
doSomething1();
doSomething2();
}
Run Code Online (Sandbox Code Playgroud)
这里的问题可以在不使用全局变量的情况下通过简单地ss在函数之间传递变量来解决。但是,由于多个函数需要访问该变量,这会变得更加复杂ss。而且通过ss很麻烦。没有太多方法可以避免应用程序脚本中的全局。不支持模块。如果您使用 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*/}
Run Code Online (Sandbox Code Playgroud)
添加菜单将失败,因为此行之前onOpen已加载,并且此行需要权限/授权,而作为简单触发器,不会使用任何需要授权的代码运行。SpreadsheetApp.openById(/*SPREADSHEET_ID*/)onOpenonOpen
如何声明全局变量而不遇到授权错误?
这个问题可以通过使用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*/}
Run Code Online (Sandbox Code Playgroud)
在这里,我们在对象内部使用getter,而不是直接声明ss. 以这种方式使用,SpreadsheetApp.openById()虽然是在全局范围内声明的,但永远不会在全局范围内调用。doSomething1它仅在执行时加载。此外,当从 访问该方法时,不会再次调用该方法doSomething2,因为第一次访问时 getter 会被删除并替换为实际值。
虽然代码变得有点庞大,但是这样解决了很多问题,而且优雅多了。
| 归档时间: |
|
| 查看次数: |
1281 次 |
| 最近记录: |