10
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

GASで重たい処理中にローディング表示する

Posted at

GASで重たい処理中にローディング表示する

ファイルの読み書き中やAPIの呼び出し時に、
ローディング表示したいなと思ったので作ってみました。

概要

  1. GASからモーダルダイアログを呼び出し
  2. モーダルダイアログでローディング表示している裏で重たい処理を実行
  3. 処理が完了したらダイアログ側に結果を通知

c2cd85c3c042b69f4994e728c700af51.gif

手順

重たい関数を作る

6分を超えない範囲で重たい処理を実装しましょう
モーダルダイアログに情報を返したい時は

  • 正常終了時:returnで戻り値を返す
  • 異常終了時:throwでエラーオブジェクトを返す

とすることで、モーダル側で処理を分けることが出来ます

main.gs
function verySlowFunc() {
  // 時間のかかる処理
  Utilities.sleep(3 * 1000);

  // 終了時に表示する文字列
  return 'Success';
  // 失敗時は例外を投げる
  // throw new Error('Failuer!');
}

ローディング画面を呼び出す部分を作る

モーダルダイアログを呼び出す処理を作成します。
ダイアログはクライアントサイドで動くので
サーバーサイドから渡したい情報は、グローバル変数を利用して共有します。
※このケースでは、関数名を文字列として受け渡し

main.gs
/** ローディング画面に受け渡すためのグローバル変数 */
let loading_cb = '';

/** ローディング画面の呼び出し*/
function beginLoading() {
  // ローディング中に実行する関数をコールバックに指定
  loading_cb = 'verySlowFunc';

  const html = HtmlService
    .createTemplateFromFile('load.html')
    .evaluate();
  SpreadsheetApp.getUi().showModalDialog(html, '重たい処理...');
}

ローディング画面を実装する

こんな感じでhtmlを書きましょう。
GASのIDEでファイル追加すればOKです

以下の箇所で、サーバーサイドでセットした
グローバル変数を参照して、callBack関数に渡します。

load.html
  <script type="text/javascript">
    window.onload = (_ => {
      google
        .script
        .run
        .withSuccessHandler(onSuccess)
        .withFailureHandler(onFailure)
        .callBack(<?= loading_cb ?>); // コールバック関数を読み込む
    });
  </script>

GASにはScriptletという仕組みがあり、
こんな感じのフォーマットで記述した部分は事前にサーバーサイドで実行された後でHTMLとして解釈されます

<?= loading_cb ?>

コールバック用APIを作成する

モーダル(クライアントサイド)から呼び出すための関数を作成します。

本当は関数オブジェクトを直接渡して実行したい所ですが、
クライアントサイドのgoogle.script.runで指定可能な関数は
HTMLファイル毎に固定なので汎用性があまり高くありません。

そのため、関数名の文字列をキーとしたテーブルを用意して
コールバック用APIに渡された文字列に対応した関数を呼び出す設計にしています。

main.gs
/**
 * ローディング画面からのコールバック用関数
 * @param[in] {string} func 呼び出す関数名
 */
function callBack(func) {
  // コールバックテーブル
  const callBackTable = {
    'verySlowFunc': () => verySlowFunc(),
  };

  // コールバック関数実行
  if(callBackTable[func])
    return callBackTable[func]();

  // テーブルに無ければエラー
  throw new Error('no callback');
}

こうすることで、1つのload.htmlに対して
複数のコールバック関数を割り当てることが可能になり、
コードの見通しが良くなりました

まとめ

今回はローディング画面のコールバック関数という形で
サーバーサイドとクライアントサイドの連携を行いました。

どちらもJavascriptベースで処理が書けるので、
慣れれば割と簡単に意図した処理が実現出来るかと思います🙌

10
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?