-1

All of this code is in a file called juggling_async.js. It is exercise 9 of node school.

This code is broken (I wrote it):

var http = require('http');
var bl = require('bl');
var result = [];
var count = 0;

for(var i=0;i<3;i++) {
    http.get(process.argv[2 + i], function(res){
        res.pipe(bl(function(err,data){
            if(err) return console.log(err.message);
            result[i]  = data.toString();
            count++;
            if(count == 3) {
                for(var j=0;j<result.length;j++) {
                    console.log(result[j]);
                }
            }
        }));
    });
}

It logs out: "undefined"
"undefined"
"undefined"
"[this is a string of text]"

This code solves the problem:

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) // yay! we are the last one!
        printResults()
    }))
  })
}

for (var i = 0; i < 3; i++)
  httpGet(i)

In my mind, my broken code should work. I start looping through i, i starts at 0, I make an http.get request using the http library and the http.get takes a callback where res is the response of the http.get request. function(res) is the callback which doesn't run until the get request returns right? At that point, i is still 0 and so I set data.toString() to result[0] right? The first element of the result array then should contain something right and not be undefined?

Obviously, my mind and code are broken. Where am I going about this incorrectly?

BTW:, I read the related posts on closures and I still don't understand why my code is broken or where it's failing.

Jwan622
  • 11,015
  • 21
  • 88
  • 181

1 Answers1

1

In the first example, your variable i is a reference, so the loop finishes with i at the max value, and THEN all your callbacks are called and use the reference i - which would be set to the same state as the end of the for loop.

In your second one, the count gets saved into another variable in a closure.

Hyo Byun
  • 1,196
  • 9
  • 18