この背後にある (あまり認めない...) 面白い質問は、私が実際にどのように機能するかを理解せずに使用する回避策についての実際の質問です。
最初に私の使用例の簡単な説明です。これはすべて、サイドバーに表示されるドキュメントにバインドされた UiApp で行われています。
GAS で書かれた差し込み印刷アプリケーションで数百の文書を作成して電子メールで送信する必要があります。もちろん、5 分の実行時間制限に達することなく 1 つのバッチで処理するには時間がかかりすぎるため、タスクを完了するためにいくつかの異なる回避策を試しました。
- プロセスを開始するときにタイム スタンプ (ScriptProperties に格納されている) を使用し、制限に近い事前定義された値に達すると、現在の値 (ポインター、便利な変数...) を格納し、ユーザー インターフェイスに戻ってユーザーに続行するように求めます (か否か)。これはかなりうまく機能しますが、タスク全体を完了するには人間の行動が必要です。
- そこで、最初のハンドラー呼び出しで作成したタイマー トリガーを使用してソリューションをセットアップし、このトリガーがドキュメント作成/送信関数を呼び出します。これもうまく機能していますが、UI を更新できるのはハンドラー関数のみであるように見えるため、関数と呼ばれるトリガーは UI とやり取りできません。問題は、進行状況を表示したり、プロセスがいつ終了したかを簡単に表示したりできないことです。
- それから、ちょっと前に楽しみのために書いた小さなアプリを思い出しました。それはサーバー ハンドラー トリガーとして checkBox を使用するタイマーでした (古い Google フォーラムで Romain Vialard によってずっと前に提案されたアイデアから)、これを試すことにしました。私のメール送信プロセスのトリック。
それは完全に機能します。私は 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
}