初windows kobito投稿
learnyounodeよりお題
learnyounode: https://github.com/workshopper/learnyounode
ASYNCジャグリング
引数で与えた、3つのurlをgetして順番に表示する
それぞれのページの応答時間はまちまちで、指定した順に応答があるとは限らない。
非同期処理でそれぞれページを取得し、最後に表示をする。
async.jsを使えば非同期処理は簡単にできるが、それは使うなという縛り
まず自分で書いたパターン
satatusオブジェクトで、url文字列をキーに取得値を管理。
コンテンツが取得し終わったら、statusに格納し、checkをよぶ。
checkでは、すべてのキーに対してデータが格納されれば、表示をする。
var http = require('http')
var status = {}
status[process.argv[2]]=""
status[process.argv[3]]=""
status[process.argv[4]]=""
Object.keys(status).forEach(function(key){
http.get(key,function(response){
var buf = ""
response.on('data',function(data){
buf += data.toString()
})
response.on('end',function(){
status[key] = buf
check(status)
})
})
})
function check(status){
var count = 0
Object.keys(status).forEach(function(key){
if(status[key])
count++
})
if(count==3){
Object.keys(status).forEach(function(key){
console.log(status[key])
})
}
}
最初、ページをゲットする処理で
for(var i =2; i<4; i++){
http.get(process.argv[i],function(response){
var buf = ""
var name = preocess.argv[i]
response.on('data',function(data){
buf += data.toString()
})
response.on('end',function(){
status[name] = buf
check(status)
})
})
}
って書いてしまっていたけどこの場合、nameがループごとに上書きされてしまって思うように動かなかった。
関数内でvarで定義しているのだから、イメージとしてはhttp.getの処理毎にスコープが別で作られると思ったのだけど違った。Object.keys(status).forEachだとイメージ通りの動作になった。
ここら辺はまだ正直自分の中で整理できていない。
回答例はこちら
var http = require('http')
var bl = require('bl')
var results = []
var count = 0
function printResults () {
for (var i = 0; i < 3; i++)
console.log(results[i])
}
function httpGet (index) {
http.get(process.argv[2 + index], function (response) {
response.pipe(bl(function (err, data) {
if (err)
return console.error(err)
results[index] = data.toString()
count++
if (count == 3)
printResults()
}))
})
}
for (var i = 0; i < 3; i++)
httpGet(i)