Ankit
Ankit

Reputation: 33

Performing Sync Get request using Node.js

I am trying to get the response received from the server in the same order as there url's were passed as command line arguments.But it does not perform sync operation please help. I am relatively new to javascript and node. please find my code below:

var http = require('http');
var bl = require('bl');
var fs = require('fs');
var q = [];
var count = 0;
q[0] = getRequest(process.argv[2]);
q[1] = getRequest(process.argv[3]);
q[2] = getRequest(process.argv[4]);
function getRequest(url) {
    var val;
    http.get(url,function (res) {
        res.on('end', function () {
            count++;
        }),
            res.pipe(bl(function (error, data) {
                val = data.toString();
                if (error) {
                    console.log(error);
                }
                else {
                    console.log(val);
                }
            }))
    }).on('error', function (e) {
            console.log("Got error: " + e.message);
        });
    return val;
}

if (count == 3) {
    for (var i = 0; i < q.length; i++) {
        console.log[q[i]];
    }
}

Upvotes: 2

Views: 7353

Answers (3)

Bojoer
Bojoer

Reputation: 948

Another approach to it, without using any plugins or add-ons for the async implementation:

var http = require('http')
var bl = require('bl')
var results = []
var count = 0

function printResults () {
    for (var i = 0; i < 3; i++)
        console.log(results[i])
}

function httpGet (index) {
    http.get(process.argv[2 + index], function (response) {
        response.pipe(bl(function (err, data) {
            if (err)
                return console.error(data)

            results[index] = data.toString()
            count++

            if (count == 3) // yay! we are the last one!
                printResults()
        }))
    })
}

for (var i = 0; i < 3; i++)
    httpGet(i)

or without any add-ons or plugins

var http = require('http')
//var bl = require('bl') // if you want to use bl

var url1 = process.argv[2]
var url2 = process.argv[3]
var url3 = process.argv[4]

// data should return via callback = function(err, data)
function getRequest(url, callback) {

    http.get(url, function(response) {

        response.setEncoding('utf8')

        response.on('error', function(e) {
            callback(error);
        })

        var allData = ''
        response.on('data', function(data) {
            allData += data
        })

        response.on('end', function() {
            callback(null, allData)
        })

        // Would be the result using bl
        /*
        response.pipe(bl(function(err, data) {
            callback(err, data.toString())
        }))
        */

    })

}

// This can be placed in a for loop
getRequest(url1, function (e, data) {
    console.log(data)
    getRequest(url2, function (e, data) {
        console.log(data)
        getRequest(url3, function (e, data) {
            console.log(data)
        })
    })
})

So you were not that far off with your first try!

Upvotes: 2

damphat
damphat

Reputation: 18956

var http = require('http');
var bl = require('bl');

// data should return via callback = function(err, data)
function getRequest(url, callback) {
    http.get(url, function(res) {
        res.pipe(bl(function(error, data) {
            callback(error, data);
        }))
    }).on('error', function(e) {
        callback(error);
    });
}

// npm install async
var async = require('async');

async.map(process.argv.slice(2), getRequest, function (err, data_array) {
    data_array.forEach( function (data, i) {
        console.log(i, data.toString('utf8'));

    });
})

save as test.js and run from terminal:

npm install bl
npm install async
node test.js http://api.openkeyval.org/hello1 http://api.openkeyval.org/hello2 

output:

0 'hello one'
1 'hello two'

async.map will call sequently getRequest like this:

getRequest(url1, function (e, data) {
    console.log(data);
    getRequest(url2, function (e, data) {
        console.log(data);
        getRequest(url3, function (e, data) {
            console.log(data);
        })
    });
});

Upvotes: 3

user568109
user568109

Reputation: 47993

Since it is asynchronous return won't be useful. But you can push it q when you have the result.

        res.pipe(bl(function (error, data) {
            val = data.toString();
            q.push(val);
            if (error) {
            ...

Or if you want to use the count, you can do:

        res.pipe(bl(function (error, data) {
            val = data.toString();
            q[count] = val;
            if (error) {
            ...

Then you can simply call :

getRequest(process.argv[2]);
getRequest(process.argv[3]);
getRequest(process.argv[4]);

Upvotes: 1

Related Questions