I'm new to javascript and node.js, so this might be basic javascript problem..
I'm solving this Juggling Async problem in LearnYouNode, but I don't know why my code isn't working.
my code:
const http = require('http');
var URLs = [process.argv[2], process.argv[3], process.argv[4]];
var strs = ["", "", ""];
var ctr = 0;
for(var i = 0; i < 3; i++){
http.get(URLs[i], (response) => {
response.setEncoding('utf8');
response.on('data', (data) => {
strs[i] += data;
});
response.on('end', () => {
ctr++;
if(ctr == 3){
console.log(strs[0]);
console.log(strs[1]);
console.log(strs[2]);
}
});
});
}
My code doesn't work, but this code does:
const http = require('http');
var URLs = [process.argv[2], process.argv[3], process.argv[4]];
var strs = ["", "", ""];
var ctr = 0;
function httpGet(i){
http.get(URLs[i], (response) => {
response.setEncoding('utf8');
response.on('data', (data) => {
strs[i] += data;
});
response.on('end', () => {
ctr++;
if(ctr == 3){
console.log(strs[0]);
console.log(strs[1]);
console.log(strs[2]);
}
});
});
}
for(var i = 0; i < 3; i++){
httpGet(i);
}
The code works only by making it as a function. Why is this?
EDIT: the problem is that the "strs[i] += data" part doesn't work!
EXPECTED: "As cross as a turps how gutful of freckle. You little ripper gone walkabout mate you little ripper khe sanh. "
ACTUAL: ""
EXPECTED: "As dry as a milk bar when mad as a ambo. Stands out like a stickybeak my lets get some larrikin. He hasn't got a budgie smugglers and stands out like a show pony. "
ACTUAL: ""
EXPECTED: "You little ripper cockie where we're going digger. Grab us a bush oyster heaps you little ripper dero. Lets get some apples mate gutful of compo. "
ACTUAL: ""
When the http.get run the value of ' i ' is 2 in the loop ' for ' because it is the last value that ' i' has in loop. Instead in function the value is correct ' 0 ' ' 1' and '2' because passing the ' i ' in function you have a local variable in function.
It is related to the closure: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
The reason why wrapping the async method in a function works better is because the passed on index i
is the same as the expected index.
for (var i = 0; i < 3; i++) { setTimeout(function() { console.log(i) }, 1000); }
The output is always 3
, because the for loop finishes before the async method is done with the call.
You can however use the let
keyword in es6 to keep blocked scope variables.
for (let i = 0; i < 3; i++) { setTimeout(function() { console.log(i) }, 1000); }
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.