12
8

More than 3 years have passed since last update.

google.script.run が Promise を返すようにする

Posted at

期待を返せ

google.script.run は withSuccessHandler や withFailureHandler でコールバックを登録する仕様となっており、 Promise を返してくれません。
async / await ですっきり書きたいですよね。

理想
(async ()=> {
  const data1 = await google.script.run.myFunction();
  const data2 = await google.script.run.myFunction2(data1);
  console.log(data1);
  console.log(data2);
})();
現実
google.script.run
.withSuccessHandler( data1 => {
  google.script.run
  .withSuccessHandler( data2 => {
    console.log(data1);
    console.log(data2);
  })
  .withFailureHandler(console.error)
  .myFunction2(data1);
})
.withFailureHandler(console.error)
.myFunction();

Promiseを返さないなら自作関数で包んでしまえ

というわけで google.script.run を元に Promise を返す関数を動的に定義します。

const ServerScript = new class {
  constructor() {
    const createAsyncFunction = (methodName) => function() {
      return new Promise( (resolve, reject) => {
        google.script.run
        .withSuccessHandler(resolve)
        .withFailureHandler(reject)
        [methodName]
        .apply(null, arguments);
      });
    }.bind(this);
    for (const methodName in google.script.run) {
      const type = google.script.run[methodName].prototype.constructor.name;
      if (type != methodName) {
        this[methodName] = createAsyncFunction(methodName);
      }
    }
  }
};
(async ()=> {
  const data1 = await ServerScript.myFunction();
  const data2 = await ServerScript.myFunction2(data1);
  console.log(data1);
  console.log(data2);
})();

for 文の中の if は withSuccessHandler や withFailureHandler を弾くためのものなので、別に無くても問題ないです。呼ばなければ良い話ですから。

また、この条件でも doGet などが入ってきてしまうのですが、呼んでもエラーなどは起きずに undefined が返ってきます。元々の google.script.run からそのような動きをするようなので、こちらも特に気にしないことにします。

以上、快適なGASライフを!

12
8
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
12
8