Promise の使い方や kintone カスタマイズにおける非同期処理については、チュートリアルの次の記事を参照してください。
Promise と async/await
kintone カスタマイズで非同期処理をする
(著者:武井 琢治)
ここでは、kintone.Promiseについて、
お悩みの末にここにたどり着いたkintoneカスタマイズ初心者の方向けに、
本当の要点だけに焦点を絞り、一番優しい「やんわり記事」をめざして書いていきます。
結論:kintone.Promiseとは
な~んか処理の順番が上手くいかない時や、
な~ぜか上手く処理が反映されない時に使うと解決できるかもしれないもの。
使いどころ
上図のように、kintoneのレコード保存イベントで使用することが多いです。
使用例
上図のように、売上レコードを作成したら、即在庫数に反映させるようなシステムを作成します。
アプリの準備
以下の3つのアプリを用意します。
■商品マスタ
フィールドコード | フィールドタイプ | 備考 |
---|---|---|
商品名 | 文字列(1行) | |
単価 | 数値 |
■売上管理
フィールドコード | フィールドタイプ | 備考 |
---|---|---|
商品名 | ルックアップ | 商品マスタの商品名をコピー元のフィールドとする。 |
単価 | 数値 | 商品マスタの単価をコピーする。 |
売上数量 | 数値 | |
在庫連携 | ラジオボタン | 未処理/連携済/エラー |
■在庫管理
フィールドコード | フィールドタイプ | 備考 |
---|---|---|
商品名 | ルックアップ | 商品マスタの商品名をコピー元のフィールドとする。 |
単価 | 数値 | 商品マスタの単価をコピーする。 |
在庫 | 数値 | |
評価額 | 計算 | 計算式に「単価 * 在庫」 |
アプリテンプレート
kintone.Promise超入門.zipをダウンロードし、環境に適用してください。
アプリテンプレートの使用方法はこちらを参照してください。
適宜ご利用ください。(JavaScriptファイルは抜いてあります)
JavaScriptファイルの準備
売上管理アプリの「アプリの設定 > JavaScript / CSSでカスタマイズ」に以下のサンプルコードを設定します。
サンプルコードはエディタにコピーして、ファイル名を「sales.js」、文字コードを「UTF-8」で保存します。
※ファイル名は任意ですが、ファイルの拡張子は「js」にしてください。
※7行目の「zaikoAppId」の値は、作成した在庫管理アプリのアプリIDに変更してください。
プログラムの解説
kintoneのイベントにおいて、基本的に処理の最後はreturn event;とすることが多いかと思いますが、
ここでは処理の最初にこのkintone.Promiseをreturnしています。
在庫が売上数量に満たない場合は、
保存後の売上レコードのラジオボタンを「エラー」にしています。
resolveはkintone.Promiseを使うためのおまじないです。
(具体的には成功したkintone.Promiseオブジェクトを生成し返却しますが、
よく分からなければ「kintone.Promiseの最終地点に置くもの」で良いと思います。)
在庫レコードを上書きした上で、売上レコードのラジオボタンを「連携済」にしています。
resolveのおまじないはどの道をたどっても最後に通るようにしましょう。
やりがちな失敗パターン
kintone.Promiseを使用せずに何とかしようとすると、多くの場合、このように書きたくなります。
この場合、売上レコードの「record.在庫連携.value」は変更されずに「未処理」のままでレコード登録されてしまいます。
その理由は、
や、
の処理よりも先に、
の処理が終わってしまうためです。
このように上から順番の処理にならないことを「非同期処理」と呼びます。
このkintone.Promiseを使用することで、
や、
の上から順番に終わってくれない非同期処理の終了を待ってくれるのです。
「準備できたので、もう待ってくれなくてもいいですよ」の合図がresolveのおまじないというわけです。
その他の用途
以上が基本的な使用方法です。
以下は発展情報ですので「そういうのもあるのか」程度の認識で問題ありません。
その他の用途例
- 繰り返し構文の中で非同期関数を使用し、すべてが完了してから実行したい処理がある場合。
- 非同期関数の返り値によった処理をしたい場合。
- 様々な処理ルートがある中で一つでもkintone.Promiseがresolveされたら実行したい処理がある場合。
- then()によるメソッドチェーンでコールバック地獄を回避したい場合。
……など。
複数のkintone.Promiseを待ち合わせする例
売上管理アプリでレコード編集する場合、在庫の書き換えを行うだけでなく、
当該レコードに「〇個売りました。」というコメントを投稿する例をご紹介します。
流れとしては、以下のようになります。
サンプルコード
プログラムの解説
在庫を連携する処理です。
前回のサンプルと違って、zaikoChange変数にkintone.Promiseを入れています。
その他の処理はほぼ変わらずですが、最後のresolve()で「"エラー"」や「"連携済"」の文字列を渡していることを押さえておいてください。
編集/保存した売上レコードにコメントを登録する処理です。
こちらも同じくcomment変数にkintone.Promiseを入れています。
この部分、よく見ると「kintone.Promise.all」になっています。
これにより、[zaikoChange(=在庫連携処理), comment(=コメント投稿処理)]の両方の処理が終わるまで待ち合わせることができます。
処理が終わったら、「処理完了!」のアラートを表示します。
その後「results[0]」を参照して分岐していますが、
この「results[0]」には上記在庫処理のresolve()で渡した文字列が入っています。
従って、渡されて来た文字列によって処理を分岐することが可能となり、
渡された文字列が「"連携済"」なら売上レコードの在庫連携を「連携済」にし、
渡された文字列が「"エラー"」なら売上レコードの在庫連携を「エラー」にして処理を完了します。
※同様の待ち合わせ処理は下記のようにthen()でつなげることでも実現可能となります。
終わりに
kintone.Promiseの勘所について、一番簡単にお伝えする試みでしたが、いかがでしたでしょうか。
ここだけ押さえておけば、後はkintone.Promiseを更に便利に使うもよし、
あるいは全く別な手段で作り上げるもよしと、活路を開くことができるのではないかと思います。
皆様の素晴らしいkintoneカスタマイズライフの一助になれたら幸いでございます。
サンプルコードは、どこにあるのでしょうか?この記事の中には見当たりません。
近藤史人さん
こんにちは。cybozu developer network運営事務局です。
本記事内の黒背景のコード部分がサンプルコードになります。閲覧できない状態でしょうか?
(例)
ありがとうございます。今日は見えています。
たぶん、会社のネットワーク環境で黒い部分がブロックされていたのじゃないかと思います。
別のネットワーク環境では見ることが出来ました。
ありがとうございました。
近藤史人さん
良かったです。ご確認ありがとうございました。
お世話になっております。初心者でございます。
『複数のkintone.Promiseを待ち合わせする例』
のサンプルで体験しておりますが、「売上管理」に初期登録し保存すると【在庫連携】は未処理のままとなってます。編集すると【連携済】となり、「在庫管理」の在庫数を減ることができますが、これは初期登録で【連携済】となり、「在庫管理」の在庫数を減ることは可能でしょうか?よろしくお願い致します。
サラ様
>編集すると【連携済】となり、「在庫管理」の在庫数を減ることができますが、これは初期登録で【連携済】となり、「在庫管理」の在庫数を減ることは可能でしょうか?
手順通りに実行すると、想定のそのようになるかと思います。
注意点としては、以下2点くらいですので、再度ご確認下さい。
お世話になっております。
お返事いただき、ありがとうございます。
その2点通り致しましたが、初期登録ではなにも変わらないですが・・
横合いから、しかも1年以上たっていますが失礼します。
『複数のkintone.Promiseを待ち合わせする例』
ではイベントがapp.record.edit.submitになっていますので初期登録(create)時は反応しないのではないでしょうか。
app.record.create.submitをイベント条件に追加すると動くのではないかと思いますが…
(上記、動作確認はしていません。念のため)