LoginSignup
0
0

More than 5 years have passed since last update.

learnyounode AYNCジャグリング

Last updated at Posted at 2015-05-12

初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)



0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0