Kintone APIの実行順序について

初心者的な質問ですみませんが、どうしても解決できず
質問させて頂きます。
一覧画面表示時に2つのAPIの処理を行い、
その後に取得した内容を使用する処理をしたいのですが、
思うように動きません。
非同期処理などを使えば動くのだろうとは思いますが
よくわからず困っています。

理想は下記のように動いて欲しいです。
index.show Start
check 2
check 11
check 12
index.show End

  kintone.events.on(app.record.index.show, function (event) {
    //==================================================================
    //  対象のアプリIDの全フィールド名を取得
    //==================================================================
    console.log(“index.show Start”) ;

    //フィールド名を取得APIのパラメータ
    var body = {
        ‘app’: kintone.app.getId()
        };
   
    //配列初期定義
    var outputfields = [] ;
   

    //対象のアプリIDの全フィールド名を取得
    kintone.api(kintone.api.url(‘/k/v1/app/form/fields.json’, true), ‘GET’, body, function(resp) {
        //success
        console.log(“check 2”) ;
       
        //取得したレスポンスのキー
        const vKeys = Object.keys(resp.properties);
          
        for (let i = 0; i < vKeys.length; i++) {
          //フィールド名を配列にセット
          outputfields.push(resp.properties[vKeys[i]].code) ;
        }
      }, function(error) {
        //error
        alert(“全フィールド名を取得” + “Err”) ;
        console.log(error);
    });

    //==================================================================
    //  アプリ情報を取得
    //==================================================================
    console.log(“check 11”) ;
   
    //アプリ名称
    let vMyApName = “” ;
   
    //アプリ情報を取得APIのパラメータ
    var body = {
        ‘id’: kintone.app.getId()
        };
       
    //アプリ情報を取得
    kintone.api(kintone.api.url(‘/k/v1/app.json’, true), ‘GET’, body, function(resp) {
        //success
        console.log(“check 12”) ;
       
        //アプリ名称
        vMyApName = resp.name ;
      }, function(error) {
        //error
        alert(“//アプリ情報を取得” + “Err”) ;
        console.log(error);
    });
   
   
    console.log(outputfields) ;
    console.log(“ApName=” + vMyApName) ;
    console.log(“index.show End”) ;
  });

こんにちは!
非同期処理難しいですよね:sweat_drops::sweat_drops:

kintone.api( ~~~~
の処理は、とりあえずサーバーに「これPOSTしてください~、GETしてくださーい」みたいなお願いを投げて、返事が帰ってくるまで待たずに次の処理に言ってしまいます。コレが非同期な動きの原因です。

//対象のアプリIDの全フィールド名を取得 
// ゲットしてきて~ という
kintone.api(kintone.api.url('/k/v1/app/form/fields.json', true), 'GET', body, function(resp) {
      //success
        console.log("check 2") ; //←GETのAPIでrespを取って戻ってくるまでは動き始めない
~~~省略~~~~

});
//==================================================================
// アプリ情報を取得
//==================================================================
// GETしてくるのを待たずに↓この処理始めちゃう
console.log("check 11") ;

この非同期な動きを順番通りに動かすにはどう処理すればいいかというと、

kintoneにおけるPromiseの書き方の基本
のページの
「Promiseを利用する(複数回)」のところあたりから具体的な書き方が書いております。
ぜひ試されてみてください:eyes::sparkles::sparkles:

最初の kintone.api(~~~ の呼び出しの前に return を書くのをお忘れなく:eyes::sparkles::sparkles:

juridonさん、コメントありがとうございます。

ほんと書き方を見てもイマイチ理解できず・・

promise?async?どっちで書く?どう書くのが綺麗?って悩み中です。

ちゃいな嬢さん

「書き方を見ても・・・」とのことですが、
Promise、async/awaitあたりはkintone&JavaScriptの中級者以上の方で、読んで理解できるレベル感だと思います(ToT)
ですので、1つずつコードを書いて試しながら掴んでいくしかないかと思います(ToT)

遠回りに感じられるかも知れませんが、実行順序で混乱されている状況を考えると、
テスト用のアプリを準備して、コードを書いて試してみるのが一番なのではないかとおもいます(><)

というわけで「kintoneにおけるPromiseの書き方の基本」にあるコードを上から順番に試されてみて、
Promiseとasync/awaitの違いなどを体験されて、その後コードをキレイにまとめるようにするのがいいかと思います。

※コードをキレイに書けるようにされたい!というところや、console.log(“XXX”);でConsoleに表示させて動きの順番を試されているの、とってもイイと思います!!!

「イマイチ理解できない部分」を「具体的にどのコードのどの行」などのように
書いていただけるとご助言できるかも知れません:eyes::sparkles::sparkles:

juridonさん

返信遅くなりすみません。

書き方の基本は見てなんとなくこうなのかな・・とは理解しているのですが

実コードになるとどう書く?となっています。

上のコードで言えば記載している通り

index.show Start
check 2
check 11
check 12
index.show End

のように上から順番に実行したいです。

また各処理を別function にした場合の呼び方もわかりません。

例えば対象のアプリIDの全フィールド名を取得の処理を独立させ

function FieldAllGet(){

省略

}

とした場合に、

kintone.events.on(‘app.record.index.show’, function (event) {

  FieldAllGet()

  xx()

}

としても、上から下には流れないなと。

すみません、説明が下手で

こんばんは!

kintoneにおけるPromiseの書き方の基本
のページ(長いですが)の、真ん中あたりに↓こういうところがあって、

ここのアプリとコードを実際に作ってやってみてください。

>書き方の基本は見てなんとなくこうなのかな・・とは理解しているのですが

実際にテスト的にアプリを作って、コードを実際に書いて動かすのがいちばん大切です(ToT)
遠回りに感じられるかも知れませんが、一度やってみられて、動いたコード内で色々と弄って、動きを把握するのが一番理解も早いです。
アプリを作ってみて、コードを書いてみて、動かしてみて、どうなるか?の繰り返しで皆さん学んでいってると思います。
頭で理解だけではプログラミングは難しいと思います。手を動かさないと身につかないとおもいますので是非是非(><)

続く、アプリの概要の下にコードがあると思います。
そのサンプルコードを動かすと

// 商品名_1, 価格_1に取得したデータを代入

// 商品名_2, 価格_2に取得したデータを代入

// 商品名_3, 価格_3に取得したデータを代入

の順番に動きます。

そのサンプルコードを参考に単純にコードを組み立てるなら、下記のような感じになると思います。
そこから、要る部分、要らない部分を削りながら何をドコに書けばいいのか実験しながらコードを組み立てていく感じになると思います。

kintone.events.on(app.record.index.show, function (event) {
 console.log("index.show Start") ; // 1番目に表示
const body = {省略};

return kintone.api(kintone.api.url('/k/v1/XXXX', true), 'GET', body).then(function(resp1) {
console.log("check 2") ;// 2番目に表示
// たとえばこの↓何らかの値Aのところに kintone.api(kintone.api.url('/k/v1/XXXXX', true), 'GET', params) みたいのをかくと、次の.then(funcion(resp2) {の、resp2に帰ってきた情報が渡される
return 何らかの値A;
}).then(function(resp2) { // ←resp2 に「何らかの値A」が入った状態でこのfunction内が実行される
console.log("check 11") ;// 3番目に表示
return 何らかの値B;
}).then(function(resp3) { // ←resp3 に「何らかの値B」が入った状態でこのfunction内が実行される
console.log("check 12") ;// 4番目に表示
return 何らかの値C;
}).then(function(resp3) { // ←resp3 に「何らかの値C」が入った状態でこのfunction内が実行される
console.log("index.show End") ;// 5番目に表示
// データを反映させる
return event;
}).catch(function(error) {
// どこか途中でエラーが発生した場合の処理
console.log(error); // エラー発生したときに表示
return event;
});
});

 

それと、別functionにしようとは考えずに、まずは思い通りに動くことを目指したほうが良いかと思います:eyes:

juridonさま、ありがとうございます。

全てのコードは実行して試しています。

Qiitaもフォローさせていただきました。

わらしべ・・面白かったです。

実際に試してそこは理解できています。

juridonさまのコード例の様に入れ子にするしかないのですね。

then,thenがあまり好きじゃないので別のやり方できないかな~と考えていました。

別functionにしたいのはそれを他のロジック(アプリ)で使えたらなと思っているからです。

汎用系→vbなのでどうしてもこういう入れ子にイメージがついていかず

自分の描くロジックに組み立てれないかなと画策しています。

ありがとうございます!

ちゃいな嬢さん

そうだったのですね!失礼しました:sweat_drops::sweat_drops:
そして、フォローくださってありがとうございますm(_ _)m

私もいわゆるVB屋さんだったのでJavaScriptは苦労しました・・・。
すると、async / await のほうが良いかも知れません!

kintoneにおけるPromiseの書き方の基本
のページの「Column1: async/awaitで直感的に同期的処理を書く」のサンプルコードのように書くと、順番がわかりやすいかと思います。(エラー処理はtry…catchで囲む必要がありますが)

(function() {
'use strict';
kintone.events.on('app.record.create.submit', async function(event) { // ←function前にasync
event.record.合計.value = 0;
// 商品アプリからデータ(レコードID: 1) を取得する
// kintone.apiの前にawaitを書いて値が帰ってくるのを待つ。
var resp1 = await kintone.api(kintone.api.url('/k/v1/record', true), 'GET', {app: 1, id: 1});
// 商品アプリからデータ(レコードID: 2) を取得する
// kintone.apiの前にawaitを書いて値が帰ってくるのを待つ。
var resp2 = await kintone.api(kintone.api.url('/k/v1/record', true), 'GET', {app: 1, id: 2});
// 商品アプリからデータ(レコードID: 3) を取得する
// kintone.apiの前にawaitを書いて値が帰ってくるのを待つ。
var resp3 = await kintone.api(kintone.api.url('/k/v1/record', true), 'GET', {app: 1, id: 3});
// 取得したデータを合計して見積もりアプリに代入
event.record.合計.value = Number(resp1.record.価格.value) + Number(resp2.record.価格.value) + Number(resp3.record.価格.value);
return event;
});
})();

 

functionの定義方法も色々ありますが、名前付きの関数と無名関数というのがあって、関数宣言や関数式で定義します。
関数宣言と関数式の違いとは?[JavaScript]
関数式
アロー関数式

↑あたりが参考になるかもです:eyes:
※私はアロー関数式派です

それと、MDN Docsのページはコードをいじって試したりできるので色々と試されてみるとイイと思います!

実現したい機能が完成しますように:pray::sparkles:

juridonさま、ありがとうございます!

まだ勉強し始めて2か月ほどなので、??ばかりです。

中途半端にPG組めると、こうなるはず、こうするには等の頭でっかちに

なっていると思います。

juridonさまのコードなどでもう少し勉強してみます。