質問: ''; res.setEncoding('utf8'); res.on('data', function(chunk){ body += chunk; }); res.on('end', function(){ flag.push(body); }); }); } while(flag.length != 3){} console.log(flag); ``` 私のコールバックか変数のスコープの認識に誤りがあるかと思うのですが教えていただけますでしょうか。
回答: 最後から2行目の `while` 文が、イベントループをブロックしているのが原因です。 次のようなループを想像してみてください。 ``` var eventQueue = []; while (isLiving()) { var event = eventQueue.shift(); if (event) { event.handle(); } } ``` イベントの待ち行列があって、1つのループを回して、待ち行列からイベントを1つずつ取り出して処理しています。 いろいろ省略していますが、これは Node.js が行っていることです。 ここで、もしも `event.handle();` の中で無限ループを作ってしまったら、次のイベントを取り出して処理できないことが想像できると思います。 @ushijima さんが書いたコード `while(flag.length != 3){}` が行っていることは、まさしく "それ" です。 1. `while(flag.length != 3){}` ループによって `event.handle();` が終わらないため、次のイベントを処理できません。 2. 次のイベントを処理できないため、「`http.get` が終わった」というイベントも処理されません。そのため `http.get` のコールバック関数は実行されません。 3. `http.get` のコールバック関数が実行されないので、`while(flag.length != 3){}` から抜け出すことはできません。そして 1 に戻ります。 例えば次のようにすると、期待通りに動作するでしょう。 ``` var http = require('http'); flag = []; for(i=2; i<=4; i++){ http.get(process.argv[i], function(res){ var body = ''; res.setEncoding('utf8'); res.on('data', function(chunk){ body += chunk; }); res.on('end', function(){ flag.push(body); if (flag.length === 3) { console.log(flag); } }); }); } ``` 複数のリクエストを扱うためのより実践的な方法は、この後で`Promise`等を学ぶと得られると思います。