如何在避免权限错误的同时使用全局变量? [英] How to use global variables while avoiding permission errors?

查看:72
本文介绍了如何在避免权限错误的同时使用全局变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请参见下面的示例,

function doSomething1(){/*needs ss*/const ss = SpreadsheetApp.openById(/*SPREADSHEET_ID*/);}
function doSomething2(){/*needs ss*/const ss = SpreadsheetApp.openById(/*SPREADSHEET_ID*/);}
function doItAll(){
  doSomething1();
  doSomething2();
}

与其在两个函数中都调用电子表格,不如使用全局变量来简化

Instead of calling Spreadsheet in both functions, this could be simplified using globals as

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或其他任何地方进行函数调用.在这里使用全局变量更为优雅.但是,如果我有一个简单的触发器,就会出现问题:

The problem here can be solved without using global variables by simply passing ss variable between the functions. But This will get much more complicated with multiple functions requiring access to the ss variable. And passing ss is cumbersome. There aren't many ways to avoid a global in Apps script. Modules aren't supported. If you use a IIFE, all functions are hidden from the IDE- making a function call from IDE or anywhere else impossible. Using a global here is much more elegant. But problems arise if I have a simple trigger:

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 将失败,因为此行在 onOpen 和该行之前加载了 SpreadsheetApp.openById(/* SPREADSHEET_ID */)需要权限/授权,而 onOpen 作为简单触发器不会与任何需要授权的代码一起运行.

The menu addition onOpen will fail because this line is loaded SpreadsheetApp.openById(/*SPREADSHEET_ID*/) before onOpen and that line requires permissions/authorizations while onOpen being a simple trigger doesn't run with any code requiring authorization.

如何在不出现授权错误的情况下声明全局变量?

How to declare globals without running into authorization errors?

推荐答案

可以使用获取器.getter仅在从任何地方调用时才执行代码,从而将代码的执行封装在全局上下文中.但是,getter将在每次对该变量的调用时执行.如果在两个函数中调用了 ss ,则将执行两次 SpreadsheetApp.openById .我们可以使用惰性加载技术来避免这种情况.

This issue can be solved by using a getter. A getter executes the code only when called from anywhere, thus encapsulating the execution of the code in global context. But the getter will execute on each call to the variable. If ss is called in two functions, SpreadsheetApp.openById is executed twice. We can avoid this using lazy loading technique mentioned in the 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在第一次访问时会被删除,并被实际值替换.

Here, We use a getter inside a object instead of directly declaring the ss. Used this way, SpreadsheetApp.openById() is never called in global scope, though it is declared in global scope. It is only loaded, when doSomething1 is executed. In addition, the method is not called again when it is accessed from doSomething2, because the getter is deleted on first access and replaced with the actual value.

尽管代码变得有点笨重,但这解决了许多问题并且更加优雅.

Although the code becomes a bit bulky, this solves many problems and is much more elegant.

这篇关于如何在避免权限错误的同时使用全局变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆