Learnyounode - Jugglling Async (#9) - I Must Be Missing Something
Solution 1:
They use a counter to count the number of callbacks while I am comparing the length of two arrays (one whose length increases every callback); does that matter?
Yes, it does matter. The .length of an array depends on the highest index in the array, not the actual number of assigned elements.
The difference surfaces only when the results from the asynchronous requests come back out of order. If you first assign index 0, then 1, then 2 and so on, the .length matches the number of assigned elements and would be the same as their counter. But now try out this:
var results = []
console.log(results.length) // 0 - as expected
results[1] = "lo ";
console.log(results.length) // 2 - sic!
results[0] = "Hel";
console.log(results.length) // 2 - didn't change!
results[3] = "ld!";
console.log(results.length) // 4
results[2] = "Wor";
console.log(results.length) // 4If you would test the length after each assignment and output the array whenever you get 4, it would print
"Hello ld!""Hello World!"Solution 2:
So it turns out there were two different issues here, one of which was pointed out by @Bergi above. The two issues are as follows:
- The
.lengthmethod does not actually return the number of elements in the array. Rather it returns the highest index that is available. This seems quite silly. Thanks to @Bergi for pointing this out. - The scoping of the
ivariable is improper, and as such the value ofican change. This causes a race condition when results come back.
My final solution ended up being as follows:
var http = require('http')
var concat = require('concat-stream')
var args = process.argv.slice(2, 5)
var args_len = args.lengthvar results = []
var count = 0functionget_url_save(url, idx) {
http.get(url, function(res) {
res.setEncoding('utf8')
res.pipe(concat(function(str) {
results[idx] = str
if (++count === args_len)
results.forEach(function(val) {
console.log(val)
})
}))
}).on('error', console.error)
}
args.forEach(function(arg, i) {
get_url_save(arg, i)
})
Breaking the outtermost forEach into a method call solves the changing i issue since i gets passed in as parameter by value, thus never changing. The addition of the counter solves the issue described by @Bergi since the .length method isn't as intuitive as one would imagine.
Post a Comment for "Learnyounode - Jugglling Async (#9) - I Must Be Missing Something"