BenWS BenWS - 4 months ago 8
Node.js Question

Callbacks within http request methods - not happening in correct order

I've written a program that makes an HTTP GET request for three distinct URLs. The program is supposed to output the message body in the order the URLs are provided, however it's not doing so even though I'm making callbacks in exactly that order.

The final program is supposed to require the user to input the URLs via command line, however I've simply made variable assignments for ease of testing.

I realize this code could be more object-oriented - however I'm new to JavaScript and it's not my focus to learn how at the moment

var http = require('http')

// var url_1 = process.argv[2]
// var url_2 = process.argv[3]
// var url_3 = process.argv[4]

var url_1 = 'http://youvegotmail.warnerbros.com/cmp/0frameset.html'
var url_2 = 'http://www.3riversstadium.com/index2.html'
var url_3 = 'http://toastytech.com/evil/'

var output_1 = ''
var output_2 = ''
var output_3 = ''


function getHttp_1 (callback) {
http.get(url_1, function getResponse (response1) {
response1.setEncoding('utf8')
response1.on('data', function (data) {
output_1 = output_1 + data
})
response1.on('end', function processData() {
console.log("Printing Result 1:")
callback(output_1)
})
})
}

function getHttp_2 (callback) {
http.get(url_2, function getResponse (response2) {
response2.setEncoding('utf8')
response2.on('data', function (data) {
output_2 = output_2 + data
})
response2.on('end', function processData() {
console.log("Printing Result 2:")
callback(output_2)
})
})
}

function getHttp_3 (callback) {
http.get(url_3, function getResponse (response3) {
response3.setEncoding('utf8')
response3.on('data', function (data) {
output_3 = output_3 + data
})
response3.on('end', function processData() {
console.log("Printing Result 3:")
callback(output_3)
})
})
}

function printResults(output) {
console.log("Result")
// console.log(output)
}

getHttp_1(printResults)
getHttp_2(printResults)
getHttp_3(printResults)


EDIT:

Results I'm generally getting:

Printing Result 3:
Result
Printing Result 2:
Result
Printing Result 1:
Result


Results I'm expecting:

Printing Result 1:
Result
Printing Result 2:
Result
Printing Result 3:
Result

Answer

Welcome to the asynchronous life of node.js! As you fire off those HTTP requests, one will not wait for the request before it to finish before it fires. You are seeing this odd behavior because you are practically sending all 3 requests at once, and simply printing as you see the responses.

Edit: If you do want to see them in correct order, fire off the second HTTP request inside the callback of the first, and then the third inside the callback of the second. That guarantees you won't get the data until after each one before it finishes.

function getHttp_1 (callback) {
    http.get(url_1, function getResponse (response1) {
        response1.setEncoding('utf8')
        response1.on('data', function (data) {
            output_1 = output_1 + data
        })
        response1.on('end', function processData() {
            console.log("Printing Result 1:")
            callback(output_1)
            getHttp_2(callback)
        })
    })
}
Comments