Quantcast
Channel: ループタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 83

request をループ処理する

$
0
0

http request をすると response があるまで少々の時間がかかります。
しかし、node.js では response を待たずに次の処理に進んでしまいます。
そのため、response を待って処理するためには、promise または callback を利用して非同期処理を行う必要があります。

node.js には request-promise モジュールがあり、こちらを使用することにより簡単に非同期処理を行うことができます。
request-promise については過去に記事を書きましたのでこちらをご参照ください。
Callback 使いから Promise マスターにクラスチェンジするぞ!

と、諸先輩方には釈迦に説法なお話なのですが、自分の理解の定着のために書かせていただきました。
オレ、しっかり反復する。大事('ω')

さて、前置きはこのくらいにして、本題に入りましょう。

ID から名前を取得して表示するプログラム

  1. ID から name を検索する API』を request する
  2. response を取得したら IDname を表示する
  3. 1~2 を ID リストの分だけ繰り返す

こんなループをするプログラムにしたいと思います。

for や while を使ったループで request すると…?

単純にループさせるだけなら forwhile を使えば実現します。

request-loop.js
const idList = ["sample001@shop","sample002@shop","sample003@shop"];
class setOptions {
    constructor(id) {
        // API を request するためのオプションをセット(内容は割愛)
    }
}
for(let i = 0; i < idList.length; i++){ // 3 の処理
    request(new setOptions(idList[i])).then((response) => { // 1 の処理
        console.log(idList[i] + " : " + response); // 2 の処理
    }).catch((error) => { console.log(error) }); 
}

しかし、実行結果がこうなります。

sample002@shop : サンプル次郎
sample001@shop : サンプル太郎
sample003@shop : サンプル四郎

順番がバラバラですね。
結局、forwhile を使う場合には非同期処理になるため、response を待たずに次の request を行ってしまうためです。
for がやっている実際の処理は、こんな感じなのでしょう。

for部分の実際の処理
request(new setOptions(idList[0])).then((response) => {
    console.log(idList[0] + " : " + response);
}).catch((error) => { console.log(error) }); 
request(new setOptions(idList[1])).then((response) => {
    console.log(idList[1] + " : " + response);
}).catch((error) => { console.log(error) }); 
request(new setOptions(idList[2])).then((response) => {
    console.log(idList[2] + " : " + response);
}).catch((error) => { console.log(error) }); 
}

せっかくの request-promise でも、別々に呼び出してたら意味ありませんよね。
結局、非同期処理されて、順番は守られません。

本当は、こうしたいのです。

こんな処理がしたい!
request(new setOptions(idList[0]))
.then((response) => {
    console.log(idList[0] + " : " + response);
    return request(new setOptions(idList[1]));
.then((response) => {
    console.log(idList[1] + " : " + response);
    return request(new setOptions(idList[2]));
.then((response) => {
    console.log(idList[2] + " : " + response);
}).catch((error) => { console.log(error) }); 

さて、これをループ処理にするには、どうしたら良いのでしょうか?

再起処理でループさせる

再起処理とは「自分自身を呼び出す処理が書かれている関数を呼び出すこと」です。
この方法であれば、response を待って処理することができます。

request-loop.js
const idList = ["sample001@shop","sample002@shop","sample003@shop"];
class setOptions {
    constructor(id) {
        // API を request するためのオプションをセット(内容は割愛)
    }
}
function loop(i){
    request(new setOptions(idList[i]))
    .then((response) => {
        console.log(idList[i] + " : " + response);
        i++;
        if(i < idList.length) loop(i); // ここでループする
    }).catch((error) => { errorArart(error) });    
}
loop(0);
sample001@shop : サンプル太郎
sample002@shop : サンプル次郎
sample003@shop : サンプル四郎

API で取得した値を利用して、順番通り表示することができました!(*‘∀‘)やったね!

おわりに

ここまでお付き合いいただきありがとうございました。

肝心の再起処理の部分がさらっと終わってしまったのですが、できたときは凄く嬉しかったです YO!('Д')
いや、ほんと。for 文でなんとかできないか四苦八苦していました。
まだまだ勉強が足りません。精進せな。

今回、メインではなかったので API 部分は割愛したのですが、今回の話を踏まえた上で、次回は LINEWORKS の API でやる方法を解説してみたいと思います。

ではまた!(^^)/

参考にさせていただきましたm(_ _)m

再帰処理とは (分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典)


Viewing all articles
Browse latest Browse all 83

Trending Articles