Reputation: 33
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
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
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
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