简体   繁体   中英

Node.js “LearnYouNode” juggling async function not working

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!

  1. ACTUAL: ""
  2. EXPECTED: "As cross as a turps how gutful of freckle. You little ripper gone walkabout mate you little ripper khe sanh. "

  3. ACTUAL: ""

  4. 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. "

  5. ACTUAL: ""

  6. 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. "

  7. ACTUAL: ""

  8. EXPECTED: ""

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM