http request
をすると response
があるまで少々の時間がかかります。
しかし、node.js
では response
を待たずに次の処理に進んでしまいます。
そのため、response
を待って処理するためには、promise
または callback
を利用して非同期処理を行う必要があります。
node.js
には request-promise
モジュールがあり、こちらを使用することにより簡単に非同期処理を行うことができます。
※request-promise
については過去に記事を書きましたのでこちらをご参照ください。
Callback 使いから Promise マスターにクラスチェンジするぞ!
と、諸先輩方には釈迦に説法なお話なのですが、自分の理解の定着のために書かせていただきました。
オレ、しっかり反復する。大事('ω')
さて、前置きはこのくらいにして、本題に入りましょう。
ID から名前を取得して表示するプログラム
- 『
ID
からname
を検索するAPI
』をrequest
する -
response
を取得したらID
とname
を表示する - 1~2 を ID リストの分だけ繰り返す
こんなループをするプログラムにしたいと思います。
for や while を使ったループで request すると…?
単純にループさせるだけなら for
や while
を使えば実現します。
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 : サンプル四郎
順番がバラバラですね。
結局、for
や while
を使う場合には非同期処理になるため、response
を待たずに次の request
を行ってしまうためです。
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
を待って処理することができます。
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 でやる方法を解説してみたいと思います。
ではまた!(^^)/