for文の処理について

販売品管理アプリと在庫管理アプリがあり、販売品管理アプリのサブテーブルで利用数が入力されたら、在庫管理アプリのサブテーブルに追加する処理を行いたいです。

 

for文の中でGETが走り、サブテーブルにプッシュする処理が走り、PUTリクエストボディを作って更新といった想定ですが、async / await の書き方がダメなのか

for文入る→GET→PUTリクエストボディ作成→for文の先頭に戻る(oが+1された状態)→PUTする

 

といった流れになってしまいます。

そのため、同じ利用品IDの行が3つ(行IDは別)あった場合、1つ目・3つ目は登録されますが、2つ目が登録されずに終わってしまいます。

※行IDは在庫管理アプリに既に同じ行IDがあれば登録しないようにするためのもので、一意のコードが割り当てられています。

 

ソースコードのどこが不足しているのかご教授いただけないでしょうか。

 

■ソースコード

kintone.events.on(events5, async function(event) { //レコード保存後に処理が走る

      const record = event.record;

      const year = record.年.value;

      const month = record.月.value;

      const sellItemTable = record.販売品.value

      for (var o = 0; o < sellItemTable.length; o++) {

        const getsellItemDays = sellItemTable[o].value[“販売品_日付”].value

        const getsellItemID = sellItemTable[o].value[“利用品ID_販売品”].value

        const getsellItemUse = sellItemTable[o].value[“販売品利用数”].value

        const getsellItemlineID = sellItemTable[o].value[“行ID_販売品”].value  //販売品管理のサブテーブル1行ずつに一意のコードを割り当て済み

      //在庫アプリの年・月・利用品IDが一致するレコードを探す

        const paramForGetStock1 = {

          ‘app’: stockAPP_ID,

          ‘query’: ‘年 in ("’ + year + ‘“) and 月 in (”’ + month + ‘") and 利用品ID = "’ + getsellItemID + ‘" limit 500’,

        }

       

        await kintone.api(kintone.api.url(‘/k/v1/records’,true), ‘GET’, paramForGetStock1).then(async function (resp) {

          console.log(resp);

          if(!resp.records.length) return;

          //在庫管理アプリ出庫テーブル取得

          await resp.records.forEach(async function(record) {

          const syukkoTable = record[“出庫”].value;

          //在庫管理アプリ出庫テーブルのID(列)を取得

          let syukkoTable_ID = [];

          for (var m = 0; m < syukkoTable.length; m++) {

            syukkoTable_ID[m] = syukkoTable[m].value[“ID”].value;

          }

          let appended_subtable = [];

          let subtable = [];

          //在庫アプリの出庫テーブルの中に利用管理のサブテーブルと同じ行IDがあるか。無ければ追加。あれば追加しない。

            if (!syukkoTable_ID.includes(getsellItemlineID)) {

              for (let m = 0; m < syukkoTable.length; m++) {

                subtable.push(syukkoTable[m]);

              }

            subtable.push({

              value: {

                “出庫日付”: {

                  “value”: getsellItemDays

                },

                “出庫数”: {

                  “value”: getsellItemUse

                },

                “ID”: {

                  “value”: getsellItemlineID

                }

              }

            });

            const paramForPut1 = {

              “app”: stockAPP_ID,

              “id”: resp.records[0].$id.value,

              “record”: {

                “出庫日付”: {

                  “value”: getsellItemDays

                },

                “出庫数”: {

                  “value”: getsellItemUse

                },

                “ID”: {

                  “value”: getsellItemlineID

                },

                “出庫”: {

                  “value”: subtable

                }

              }

            }

            console.log(paramForPut1);

            appended_subtable.push(paramForPut1);

            subtable = subtable.concat(appended_subtable); // 既存と追加分のサブテーブルを結合

            var put_record = {}; // レコード更新用オブジェクト

            put_record[“出庫”] = {

            value: subtable

            }

            

          await kintone.api(kintone.api.url(“/k/v1/record.json”, true), “PUT”, paramForPut1).then(function(resp) {

            console.log(resp);

           

          }).catch(function(error) {

                console.log(error);

          });

            }else {

          }

        })

        })

      }

      window.alert(“在庫管理に反映しました。”);

    return event;

  });

kintone.apiは非同期処理ですから、for文で回すと処理を待たずに先に進んでしまい思った結果が得られません。

Promise.all等を使うことをお勧めします。

 

また、拝見するに、せっかくasync/awaitを利用されているのにthenメソッドで繋いでいてはメリットを享受出来ないと思います。

async/awaitはPromise構文をより簡単にした書き方ですので、Promiseの理解、非同期処理の理解が大前提となります。

応用範囲はとても広いと思っていますので、ぜひ一度非同期処理の基礎から学ばれることをお勧め致します!

385257938812 様

 

コメントありがとうございます。

お教えいただいた通りpromiseについて調べてみました。

以下の記事を参考にしてみたのですが、GETする前でループして終わってしまいます。

https://developer.cybozu.io/hc/ja/articles/215029846-kintone-Promise%E3%81%A8%E3%81%AF

 

return newでkintone.Promiseをreturnして、PUTする際にresolve(event);でkintone.Promiseオブジェクトを生成しているつもりなのですが…

promiseの記述位置が悪いのでしょうか。

 

■ソースコード

kintone.events.on(events5, function(event) {

      const record = event.record;

      const year = record.年.value;

      const month = record.月.value;

      const sellItemTable = record.販売品.value

    return new kintone.Promise(function(resolve, reject) {

      for (var o = 0; o < sellItemTable.length; o++) {

        const getsellItemDays = sellItemTable[o].value[“販売品_日付”].value

        const getsellItemID = sellItemTable[o].value[“利用品ID_販売品”].value

        const getsellItemUse = sellItemTable[o].value[“販売品利用数”].value

        const getsellItemlineID = sellItemTable[o].value[“行ID_販売品”].value

        //在庫アプリの年・月・利用品IDが一致するレコードを探す

          const paramForGetStock1 = {

            ‘app’: stockAPP_ID,

            ‘query’: ‘年 in ("’ + year + ‘“) and 月 in (”’ + month + ‘") and 利用品ID = "’ + getsellItemID + ‘" limit 500’,

          }

          //ここで「o」がfor文で増えて終わる

          kintone.api(kintone.api.url(‘/k/v1/records’,true), ‘GET’, paramForGetStock1), function (resp) {

            console.log(resp);

            if(!resp.records.length) return;

            //在庫管理アプリ出庫テーブル取得

            resp.records.forEach(function(record) {

            const syukkoTable = record[“出庫”].value;

            //在庫管理アプリ出庫テーブルのID(列)を取得

            let syukkoTable_ID = [];

            for (var m = 0; m < syukkoTable.length; m++) {

              syukkoTable_ID[m] = syukkoTable[m].value[“ID”].value;

            }

            let appended_subtable = [];

            let subtable = [];

            //在庫アプリの出庫テーブルの中に利用管理のサブテーブルと同じ行IDがあるか。無ければ追加。あれば追加しない。

              if (!syukkoTable_ID.includes(getsellItemlineID)) {

                for (let m = 0; m < syukkoTable.length; m++) {

                  subtable.push(syukkoTable[m]);

                }

                subtable.push({

                  value: {

                    “出庫日付”: {

                      “value”: getsellItemDays

                    },

                    “出庫数”: {

                      “value”: getsellItemUse

                    },

                    “ID”: {

                      “value”: getsellItemlineID

                    }

                  }

                });

                const paramForPut1 = {

                  “app”: stockAPP_ID,

                  “id”: resp.records[0].$id.value,

                  “record”: {

                    “出庫日付”: {

                      “value”: getsellItemDays

                    },

                    “出庫数”: {

                      “value”: getsellItemUse

                    },

                    “ID”: {

                      “value”: getsellItemlineID

                    },

                    “出庫”: {

                      “value”: subtable

                    }

                  }

                }

                console.log(paramForPut1);

                appended_subtable.push(paramForPut1);

                subtable = subtable.concat(appended_subtable); // 既存と追加分のサブテーブルを結合

                var put_record = {}; // レコード更新用オブジェクト

                put_record[“出庫”] = {

                value: subtable

                }

                kintone.api(kintone.api.url(“/k/v1/record.json”, true), “PUT”, paramForPut1, function() {

                  console.log(resp);

                  alert(“在庫管理アプリに反映しました。”)

                  resolve(event);

                })

              }else{

                resolve(event);

              }

            })

          }

        }

    })

  });