kintoneAPI Promise対応イベントでコールバックを待つ方法

目的

今回やりたかったことは、
「レコード保存後にメッセージを表示して、ユーザがそれを閉じるまでページ遷移を待ちたい」
でした。

非同期処理を行うkintoneのAPI(kintone.apiやkintone.proxyなど)はkintone.Promiseを返すので、それをそのままreturnすることで完了後までページ遷移を待ってくれます。

イベント処理の記述方法 – cybozu developer network

Promise 対応イベントのハンドラー内で kintone.Promiseオブジェクトを return すると、非同期処理の完了を待って次の処理を開始します。

しかし、addEventListener()やsetTimeout()などは非同期処理の完了をイベントハンドラでキャッチすることになりますので、そのままではkintoneを待たせることができません。
もしPromiseならばreturnするだけで実現できるのですが……。

解決策

Promiseで包み、イベントで履行(fulfilled)または拒否(rejected)するようにします。
Promise((resolve, reject) => { 処理 });というコードなら、処理中でresolve()を呼べば履行、reject()を呼べば拒否となり、いずれもPromiseが完了します。

以下の例では、レコード追加画面でレコードの保存に成功した後、setTimeout()で5秒待っています。

JavaScript
kintone.events.on('app.record.create.submit.success', function(event) {
     return new kintone.Promise(resolve => {
         // 3秒後にresolve
         setTimeout(() => {resolve()}, 5000);
     });
});

今回はメッセージのトースト表示にJquery Toast Pluginを使いました。
以下にソースコード例を示します。

JavaScript
kintone.events.on('app.record.create.submit.success', function(event) {
    return new Promise(resolve => {
        $.toast({
            text: '保存しました!',
            icon: 'info',

            hideAfter: 5000,
            afterHidden: resolve
        });
    });
});

まとめ

kintoneの非同期処理はPromiseを使うことが強く推奨されています。
一方同じく、即時スコープ内に処理を書くことも推奨されている都合上、await/asyncで同期処理にすることは一般的ではないようです(不可能ではありませんが)。
今回のケース以外にも、レコードの一括取得 APIをループで回したい場合など、ついついawaitを使いたくなりますが……ちなみにその問題は再帰関数で解決できます。

kintoneカスタマイズ/プラグインを使いこなすなら、Promiseのマスターは不可欠と言えるでしょう。

コメントを残す

メールアドレスが公開されることはありません。

CAPTCHA