kintoneカスタマイズで非同期処理をしてみよう
はじめに
前回は、
kintone REST APIリクエストを送信するAPI
(kintone.api())のコールバック関数を使う方法で、kintone REST APIを実行する方法を説明しました。
この記事では、kintone.api()を使ってkintone REST APIを実行する次の3つの方法を、詳しく説明します。
方法1:コールバックを使う
kintone.api()を使ってkintone REST APIを実行するときは、第4引数に成功したときのコールバック関数を指定します。
これがAPIドキュメント内で「コールバックを使う方法」として紹介されている方法です。
前回のkintone REST APIの記事
で学んだ方法ですね。
|
|
例として、あるアプリのレコード追加画面を表示したときにkintone REST APIを実行し、商品アプリから取得したレコードの内容をコンソールに表示してみましょう。
|
|
successCallbackやfailureCallbackのように名前を付けた関数を引数に指定せず、そのまま関数を書くこともあります。
|
|
コールバックを使う方法は、kintone.api()を使うときの基本的な書き方ではありますが、注意することが2つあります。
- 非同期処理の完了を待たずに続きの処理が実行される。
- 非同期処理を何度も行うような場合に、コールバック地獄が発生しやすい。
どういうことか、詳しく確認していきましょう。
非同期処理の完了を待たずに続きの処理が実行される
レコードを保存するときに別のアプリからレコードを取得して、その結果をフィールドにセットしたいケースがよくあります。
たとえば、見積アプリのレコードを保存するとき、商品アプリに登録されているレコードの「定価」の値を「金額」フィールドへセットして保存したい、といった場面です。
このとき、コールバックを使う方法でkintone.api()を実行すると、「金額」フィールドが空のまま登録されてしまいます。
|
|
上記のコードは以下の順番で処理が進むため、「金額」フィールドが空の状態でレコードが登録されます。
kintone.api()で、レコードを取得するAPIを実行する。return eventで、イベントオブジェクトを返却する。- レコードを登録する。
- APIのリクエスト結果を受け取り、イベントオブジェクトに代入する。
非同期処理を何度も行うような場合に、コールバック地獄が発生しやすい
コールバック地獄とは、コールバック関数の中にコールバック関数があるような入れ子状態となり、コードが読みづらくなってしまう状況のことです。
たとえば、商品アプリから3つのレコードを順に取得する場合を考えてみましょう。
|
|
コールバック関数の入れ子が深くなっていて、括弧の対応関係がわかりにくくなっています。
kintone.api()の実行が増えれば増えるほど、この入れ子はどんどん深くなってしまいます。
方法2:Promiseを使う
コールバックを使う方法で発生するこれら2つの問題を解決するには、Promiseを使います。
Promiseを使うと、非同期処理を同期的に(順番に)処理でき、コールバック地獄からも解放されます。
非同期処理の完了を待たずに続きの処理が実行される問題を解決する
まずは、Promiseを使って、非同期処理の完了を待たずに続きの処理が実行される問題を解決してみましょう。
非同期処理の完了を待たずに続きの処理が実行される
をPromiseを使って書き直すと、次のようなコードになります。
|
|
ポイントは、5行目のreturn kintone.api(...)です。
kintone.api()は、コールバック関数を省略すると、Promiseオブジェクトが戻り値になります。
|
|
kintoneのイベントは、Promiseオブジェクトがreturnされると非同期処理の実行を待つしくみを持っています
*1
。
コードの例の場合は、商品アプリからレコードを取得する処理を待ってから、kintone.events.on('app.record.create.submit', ...)を完了します。
非同期処理が成功したときの結果は、then()メソッド内で受け取ることができます。
そのため、商品アプリから取得した「定価」を見積アプリの「金額」に代入する処理は、then()のコールバック関数内に記述します(6〜9行目)。
*1 一部のイベントでは、非対応です。 ^
コールバック地獄を解決する
次に、Promiseを使って、コールバック地獄を解決してみましょう。
コールバック関数を使った例
をPromiseを使って書き直します。
|
|
先ほどの
コールバック関数を使った例
と比べると、入れ子が浅くなり、コードの見通しが良くなりました。
ポイントは、6行目、9行目と13行目で、return kintone.api()しているところです。
Promiseオブジェクトをreturnしているので、kintone.api()の実行の完了を待ち、それぞれ後続のthen() 内で、その前に取得したレコードのオブジェクトを利用できます。
方法3:async/awaitを使う
非同期処理の記事
で、async/awaitを使うと、よりシンプルに非同期処理を書くことができると紹介しました。
kintone.api()でも、async/awaitを使ってみましょう。
次のコードは、 Promiseで非同期処理の完了を待たずに続きの処理が実行される問題を解決する で紹介したコードを、async/awaitで書き直したものです。
|
|
async/awaitを使うときのポイントは、次の2つでしたね。
- 実行する非同期関数の先頭に、
awaitをつける。 awaitを付けた行は、async関数で囲む。
そのため、さきほどの例では、次のように修正しています。
await kintone.api()にする(5行目)kintone.events.onのコールバック関数にasyncをつける(3行目)
Promiseでコールバック地獄を解決する の例も、async/awaitを使って書き直してみましょう。
|
|
then()でつないでいた処理がなくなり、さらに簡潔になりました!
おわりに
kintoneで非同期処理を同期的に行う方法を紹介しました。
難しい内容ですが、kintoneカスタマイズを行う上では理解が必須の知識です。
次回は
デバッグをしてみよう
について学習します。
コードが動かないときの対処法を学びましょう。