在哪里可以阅读有关GS文件执行顺序规则的文档?
为了确定问题的维度,我创建了两个简单的对象,每个对象都在自己的文件中。
1_File.gs
var ObjB = new Object();
ObjB.sayName = "[" + ObjA.sayName + "]";
0_File.gs
var ObjA = new Object();
ObjA.sayName = " I'm A ";
诸如......之类的电话。
Logger.log(ObjA.sayName + " : " + ObjB.sayName);
...得到错误......
TypeError: Cannot read property "sayName" from undefined.
如果我将代码从1_File.gs移动到0_File.gs,反之亦然,则没有错误,日志显示正确...
我是A:[我是A]
将0_File.gs重命名为2_File.gs也不会影响执行顺序,因此我假设该顺序取决于首先创建的文件。
是否没有“include”或“import”概念允许我明确执行执行顺序?
答案 0 :(得分:10)
在哪里可以阅读有关GS文件执行顺序规则的文档?
没有这样的文件,我认为不会发布任何时间。以类似的方式,C ++中静态变量的初始化顺序也是未定义的,并且依赖于编译器/链接器。
是否没有“include”或“import”概念允许我明确执行执行顺序?
是的,没有“包含”,“导入”甚至“模块”,但有libraries。
还有一个使用闭包的解决方法。贝娄是一个示例代码。通过执行测试功能,日志包含c.d
。我们的想法是在所有gs
个文件中包含一个以init
开头的函数。在这些函数中,所有全局变量都是实例化的。匿名闭包在Code.gs
文件实例化期间执行,并调用所有gs
文件的所有“init”函数。
<强> Code.gs 强>
var c;
function callAllInits_() {
var keys = Object.keys(this);
for (var i = 0; i < keys.length; i++) {
var funcName = keys[i];
if (funcName.indexOf("init") == 0) {
this[funcName].call(this);
}
}
}
(function() {
callAllInits_();
c = { value : 'c.' + d.value };
})();
function test() {
Logger.log(c.value);
}
<强> d.gs 强>
var d;
function initD() {
d = { value : 'd' };
};
答案 1 :(得分:2)
我通过在每个文件中创建一个类并确保每个类在原始Code.gs
(我重命名为_init.gs
)中实例化来解决此问题。实例化每个类充当include
的一种形式,并确保在执行任何操作之前一切都已就绪。
_init.gs
:
// These instances can now be referred to in all other files
var Abc = new _Abc();
var Menu = new _Menu();
var Xyz = new _Xyz();
var Etc = new _Etc();
// We need the global context (this) in order to dynamically add functions to it
Menu.createGlobalFunctions(this);
function onInstall(e) {
onOpen(e);
}
function onOpen(e) {
Menu.build();
}
课程通常如下:
menu.gs
:
function _Menu() {
this.build = function() {
...
}
...
}
答案 2 :(得分:2)
如果您有多个继承级别,则需要提供初始化函数名称,如init000Foo
,init010Bar
和init020Baz
,然后按名称对init函数进行排序执行。这将确保首先评估init000Foo
,然后Bar
,然后Baz
。
function callAllInits() {
var keys = Object.keys(this);
var inits = new Array();
for (var i = 0; i < keys.length; i += 1) {
var funcName = keys[i];
if (funcName.indexOf("init") == 0) {
inits.push(funcName);
}
}
inits.sort();
for (var i = 0; i < inits.length; i += 1) {
// To see init order:
// Logger.log("Initializing " + inits[i]);
this[inits[i]].call(this);
}
}
答案 3 :(得分:1)
Google Apps脚本中没有此类订单。它完全取决于您声明这些对象的位置以及调用函数的方式。 你能解释一下如何以及何时调用你的Logger.log()代码。 另外,你什么时候声明你的对象objA和objB? 这些将有助于我们提供更好的答案
答案 4 :(得分:1)
其他答案(即,不写任何引用其他文件中对象的顶级代码)描述了避免此问题的理想方法。但是,如果您已经编写了大量代码并重写它是不可行的,则有一种解决方法:
Google App Script似乎按照创建顺序加载代码文件。首先是最旧的文件,然后是下一个,最后创建的文件是最后一个。这是&#34;按字母顺序排序文件时编辑器中显示的顺序&#34;未经检查。
因此,如果您按此顺序拥有文件:
一个简单的解决方法是制作1_File.gs的副本,然后删除原始文件,有效地将其移动到列表的末尾。
现在0_File.gs在1_File.gs之前加载。
答案 5 :(得分:0)
这是我将如何做到这一点...
function include(filename) {
return ContentService.createTextOutput(filename);
}
function main() {
include('Obj A');
include('Obj B');
Logger.log(ObjA.sayName + " : " + ObjB.sayName);
}
var ObjA = new Object();
ObjA.sayName = " I'm A ";
var ObjB = new Object();
ObjB.sayName = "[" + ObjA.sayName + "]";