jojojohn
jojojohn

Reputation: 753

Why are my async callback functions not returning the data requests in order?

I'm learning Node.js and am working through the Learnyounode course from Node school which is amazing although it is quite a challenge and I'm and a bit confused...

The question I'm stuck on is Excercise 9- Juggling Async...

I'm trying to solve the problem:

"You must collect the complete content provided to you by each of the URLs and print it to the console (stdout). You don't need to print out the length, just the data as a String; one line per URL. The catch is that you must print them out in the same order as the URLs are provided to you as command-line arguments."

I've tried counting the callbacks in a variable called 'waiting' and then calling a complete() function when it has counted 3 callbacks, but the data still always comes back in the wrong order and I don't know why....

var http = require('http');
var bl = require('bl');
var url = []
url[0] = process.argv[2];
url[1] = process.argv[3];
url[2] = process.argv[4];
var waiting = 0;
for(i=0; i < url.length; i++) {
        var output = [];
        http.get( url[i], function(res) {
                res.setEncoding('utf8');
                res.pipe(bl(function(err,data) {
                        output.push(data.toString());
                        waiting++;
                        if(waiting == 3) {
                            complete(output);
                        }
                 }));
        });
}

var complete = function(output) {
    for(i=0; i < output.length; i++) {
        console.log(output[i]);
    }
}

Upvotes: 1

Views: 99

Answers (3)

Shilly
Shilly

Reputation: 8589

Save the value of the 'i' index for each of you requests, either by closure or by adding it as a property to the request. You can then use that index to order your responses.

Upvotes: 0

Name
Name

Reputation: 64

it's because your http get requests are asynchronous.

instead of pushing to output array do this

output[i]=data.toString();

Upvotes: 1

Armand
Armand

Reputation: 24393

The async callbacks are not guaranteed to occur in the order that the HTTP requests are made.

You could maintain the order by changing:

output.push(data.toString());

to:

output[i] = data.toString();

Upvotes: 1

Related Questions