在这背后(并非如此,我承认......)有趣的问题是关于我使用的解决方法的真正问题,而没有真正理解它是如何工作的。
首先简要介绍一下我的用例,所有这些都发生在一个文档中,UiApp出现在侧边栏中:
我必须在用GAS编写的邮件合并应用程序中通过电子邮件创建和发送几百个文档。在没有达到5分钟执行时间限制的情况下,在一批处理中需要花费太长时间,所以我尝试了几种不同的解决方法来完成任务:
它工作正常,我处理40个文件批次是每次调用(大约3分钟)然后暂停一段时间并重新开始直到它完成。 每个调用都由checkBox链接服务器处理程序触发,复选框本身在处理函数中更改,以这种方式创建自己的触发器。
我的问题(最后;-)是:知道整个过程可能需要30到60分钟,这有多精确? 这些服务器处理函数如何/为什么被视为多个进程,因为它们是从函数内部创建的?
我希望我足够清楚,(我怀疑,因为它在我的脑海里有点混乱: - )
我加入了时钟测试应用程序的代码,它给了我这个想法,它可能会让事情变得更容易理解。
function doGet() {
var app = UiApp.createApplication().setTitle('Counter/Timer');
var Panel = app.createAbsolutePanel().setStyleAttribute('padding','35');
var counter = app.createHTML().setId('counter').setHTML('<B>Timer = wait</B>').setStyleAttribute('fontSize','40px');// set start display
var clo = app.createTextBox().setName('clo').setId('clo').setValue('0').setVisible(false);//set start value in seconds
var handler1 = app.createServerHandler('doSomething').addCallbackElement(Panel);
var chk1 = app.createCheckBox('test1').addValueChangeHandler(handler1).setVisible(true).setId('chk1').setVisible(false);
app.add(Panel.add(chk1).add(counter).add(clo));
chk1.setValue(true,true);// start the process
return app}
function doSomething(e) {
var app = UiApp.getActiveApplication();
var xx = Number(e.parameter.clo);
var disp = app.getElementById('counter')
xx++ ;// replace by xx-- to count downwards
if(xx>600){ // 10 minutes timeout for example
disp.setHTML('<B> GAME OVER ;-)</B>').setStyleAttribute('fontSize','80px').setStyleAttribute('color','RED')
return app
}
var cnt = app.getElementById('clo').setValue(xx)
disp.setHTML('<B>'+T(xx)+'</B>')
Utilities.sleep(1000); // instead of sleeping do something !
// below comes the "active" part
var chk1 = app.getElementById('chk1').setValue(false,false)
var chk1 = app.getElementById('chk1').setValue(true,true)
return app;
}
function T(val){
var min = parseInt(val/60);
var sec = val-(60*min);
if(sec<10){sec='0'+sec}
if(min<10){min='0'+min}
var st = '> '+min+':'+sec
return st
}
答案 0 :(得分:10)
服务器处理程序函数调用的语句不是独立进程,因为它们“是从函数本身内部创建的”并不完全正确。
您已使用服务器处理程序chk1
设置了一个复选框元素doSomething
。每当
选中复选框,然后将分派事件发送到服务器。 (...并且您的脚本会在每次chk1.setValue()
调用时导致这些事件)checkBox
和周围的UI代码在您的浏览器中运行 - 点击“显示源代码”或使用资源管理器查看已投放的内容谷歌服务器到您的浏览器。 (警告 - 它被混淆了。但你可能会认识到你的一些字符串,以及你的客户端代码。)
以下是我们在Class ServerHandler的文档中所说的内容:
当调用ServerHandler时,它引用的函数在Apps脚本服务器上以“全新”脚本调用。
这是延长操作时间的关键:每个调度事件都会导致在一个全新的操作环境中调用doSomething()
- 就像你在另一个浏览器中打开脚本编辑器一样,然后点击“运行”在你的脚本上。 “新鲜”脚本无法访问以前运行的var值...但它也有自己的一组操作限制,包括计时器。
PS:您应该使用Lock确保服务器端处理程序是“线程安全的”,因为您正在访问可能由多个doSomething()
回调实例访问的共享资源。与此相关,可以使用此脚本达到另一个限制:
为了好玩,我在.setVisible(false)
上注释了chk1
,因此checkBox可见。然后我快速点击了几十次。时间显示无序运行,最终出现上述错误。 (几分钟后)这当然是一种人为的情况,但仍然是一种容易避免的错误状态。
PPS:我想知道是否可以使用相同的技术来分派多个并行服务器端处理程序,从而减少完成整个作业所用的时间?