はじめに
ノベルワークスのつつみん(@tsutsumin_38)です。12月に入社し、早1か月半。カリキュラムとして、cybozu developer networkのチュートリアルに取り組んでいましたが、それが終わり、次のステップで社内での実践型研修に取り組みました。
実践型研修とは、社内のメンバーにお客様役をしてもらい、要件定義~納品までの流れを経験するという研修です。お客様役のYさんが、細かいところをつっこんでくれ、かなり勉強になりました。
今回は、実践型研修に取り組む中で学んだことについて、自分が分かった範囲でアウトプットしてみようと思っています。ここからどんどん深めていくのを目標にしています。
実践型研修にて
取り組んでいたカスタマイズについて簡単に説明
担当者を変更した際に(Aアプリ(案件管理)のレコード編集画面で担当者編集)
詳細画面の一括更新ボタンで、案件に紐づくBアプリ、Cアプリのレコードの担当者も更新したい。
そのためには、案件IDをキーにしてBアプリ、Cアプリからレコードを取得し、更新をかけるというカスタマイズが必要になります。
今回は、このレコードを取得するところのみを抜粋し、学んだことアウトプットしようと思います。
修正前のコード(逐次実行)
初心者つつみんは最初、以下のようなコードを書いていました。
const updateTargetApps = [
{ appId: "2", name: "aRecords" },
{ appId: "3", name: "bRecords" },
];
for (const app of updateTargetApps) {
const records = await kintone.api(kintone.api.url('/k/v1/records.json', true), 'GET', {app: app.appId, query: `案件ID = "${event.record.案件ID.value}"`});
console.log(`${app.name}`,records);
}
挙動
await がループ内で実行されるため、1つの非同期処理が完了するまで次の処理は開始されない。
処理時間
処理時間は 各タスクの処理時間の合計 になる。
コードレビュー
Yさん:「更新するアプリとか取得するレコードが多くなったらどうですか??」
つつみん:「・・・?」
Yさん:「めっちゃ時間かかりますよね??」
つつみん:「確かに…」
Yさん:「同時に取得しちゃいたいですね?」
つつみん:「はい…。非同期処理を同期的に…?」
Yさん:「のちのちの改修も視野に入れてコード書くことが大切です。
じゃあ、それで書いてみましょう!!」
・・・・・・・・
つつみん:「ヒントください~(言ってることは分かるけど、どう書けばよいんだ…)」
と、いうわけでヒントもらって調べて、非同期処理を並行実行するコードに修正しました。
修正後のコード(並行実行)
const updateTargetApps = [
{ appId: "2", name: "atRecords" },
{ appId: "3", name: "bRecords" },
];
const promises = updateTargetApps.map(async (app) => {
const records = await kintone.api(
kintone.api.url('/k/v1/records.json', true), 'GET', {
app: app.appId,
query: `案件ID = "${event.record.案件ID.value}"`
}
);
return records;
});
const results = await Promise.all(promises);
console.log(results);
変更点
1. for...of を map に変更
各アプリの更新処理を非同期関数として定義し、updatePromises 配列に格納。
2. Promise.all を使用
Promise.all によってすべての更新処理を並行実行(非同期処理が同時に開始)し、
完了を待機。
挙動
各アプリに対するレコード取得が並行に実行される。
処理時間
処理時間は 最も時間のかかるタスクの処理時間 に等しくなる。
(更新対象アプリの数だけ処理を並行実行するため、全体の処理時間が短縮される。)
まとめ
実践型研修の中で非同期処理を並行実行する方法を学んだのでまとめてみました。場面に応じて、逐次実行と並行実行を使い分ける必要があると感じています。処理時間やメンテナンス、負荷など、考慮しなければならないことがたくさんあるので、順次学んでいきたいと思っています。