I have a snippet (below) that will generate requests based on a couple of params. It essentially creates load similar to JBehaves by distinguishing requests per user. For the most part, this works fine. Generation of requests works as expected. The results however are not working as one would expect using Promise.all(). Which leads me to my question:
Is there an issue with Promise.all()?
The format of the results may look a little wonky in this question but, essentially I'm just creating an array of users (which in itself is just an array of request results).
Actual Results
Instead of each object within the array being different, they're all the same. In most case, it appears to be the last object pushed into the array (but I haven't fully confirmed this). This behavior initially lead me to believe there was a scoping issue within my snippet but, I haven't been able to find it :(
[
[{
hostname: 'google.com',
headers: [Object],
path: '/url1/',
method: 'GET',
date: 1457395032277,
status: 200,
ttfb: 1488
}, {
hostname: 'google.com',
headers: [Object],
path: '/url1/',
method: 'GET',
date: 1457395032277,
status: 200,
ttfb: 1488
}]
]
Expected Results
I would expect that Promise.all() would return a (promise) resolving to an array with multiple objects - each one being different as to reflect the results from each task as defined in tasks().
[
[{
hostname: 'google.com',
headers: [Object],
path: '/url1/',
method: 'GET',
date: 1457395032277,
status: 200,
ttfb: 1488
}, {
hostname: 'bing.com',
headers: [Object],
path: '/url2/',
method: 'GET',
date: 1457395032280,
status: 500,
ttfb: 501
}]
]
Code Snippet
If you notice the commented out console.dir(stats): this line spits out the results as expected (different results per task) but, if I slap a .then() on the end of the reduce, the array is returned as Actual Results (vs. Expected Results)
(For brevity, let's assume request() returns a promise)
'use strict';
const request = require('./request');
const Promise = require('bluebird');
module.exports = (tests, options) => {
return Promise.all(users());
////////////
/* generate users */
function users() {
let users = [];
for (let x = options.users; x > 0; x--) {
/* https://github.com/petkaantonov/bluebird/issues/70#issuecomment-32256273 */
let user = Promise.reduce(tasks(), (values, task) => {
return task().then((stats) => {
// console.dir(stats);
values.push(stats);
return values;
});
}, []);
users.push(user);
};
return users;
}
/* generate requests per user */
function tasks() {
let tasks = [];
for (let id of Object.keys(tests)) {
for (let x = options.requests; x > 0; x--) {
let task = () => {
let delay = options.delay * 1000;
return Promise.delay(delay).then(() => request(tests[id]));
};
tasks.push(task);
};
}
return tasks;
}
};
Request Snippet
'use strict';
const https = require('follow-redirects').https;
const sprintf = require('util').format;
const Promise = require('bluebird');
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
let request = (req) => {
return new Promise((resolve) => {
let start = Date.now();
let ttfb;
let cb = (res) => {
req.status = res.statusCode;
res.on('data', (chunk) => {
if (!ttfb) ttfb = Date.now() - start;
});
res.on('end', () => {
req.ttfb = ttfb;
req.end = Date.now() - start;
resolve(req);
});
res.on('error', (err) => {
req.error = err;
resolve(req);
});
};
/* convert cookies for convenience */
if (req.headers.cookies) {
let cookies = [];
for (let cookie of Object.keys(req.headers.cookies)) {
cookies.push(sprintf('%s=%s', cookie, req.headers.cookies[cookie]));
}
req.headers.cookie = cookies.join('; ');
req.cookies = req.headers.cookies;
delete req.headers.cookies;
}
https.request(req, cb).end();
});
};
module.exports = request;
Using
$ npm --version
2.14.12
$ node --version
v0.12.9
Any help would be greatly appreciated!
Is there an issue with Promise.all()?
No.
Instead of each object within the array being different, they're all the same.
Indeed. They are all the same object.
Your request function does - for whatever reason - resolve its returned promise with its argument. As you are passing the very same tests[id] object to all requests of a batch, they all will end up with this object.
Your console.dir did show the expected results because request does mutate its argument - the test object contains different values after every call, which are subsequently logged, before being overwritten in the next call.
You should change that cb to create a new object, instead of mutating req:
function cb(response) {
let result = {
status: response.statusCode
};
response.on('data', (chunk) => {
if (!ttfb) ttfb = Date.now() - start;
});
response.on('end', () => {
result.ttfb = ttfb;
result.end = Date.now() - start;
resolve(result);
});
response.on('error', (err) => {
result.error = err;
resolve(result);
});
}
Related
I'm working with node. I have an api setup as a netlify serverless function , so that I can run a number of processes in parallel.
As part of this I want so create an array of unexecuted fetch object promises, which I can then execute in paralell using something like:
const responses = await Promise.allSettled(promiseArray);
So far I have:
for (let i = 0; i < groupedRecords.length; i++) {
const groupedRecord = groupedRecords[i];
const fetchObjects = await createFetchObjectArray(groupedRecord);
}
async function createFetchObjectArray(records) {
const fetchURL = (obj) => fetch('http://localhost:8888/.netlify/functions/meta1', {
method: 'POST',
body: JSON.stringify(obj),
headers: { 'Content-Type': 'application/json' }
});
let outputArray = [];
for (let i = 0; i < (records.length); i++) {
const record = await records.pop();
const obj = { "_id": record._id };
const fetchObj = fetchURL(obj);
outputArray.push(fetchObj);
}
return outputArray;
}
I was hoping to get an array of promises into 'fetchObjects', however they appear to be trying to execute. I'm seeing:
FetchError: request to http://localhost:8888/.netlify/functions/meta1 failed, reason: connect ECONNREFUSED 127.0.0.1:8888
how to I keep the fetch objects from executing?
Calling fetchURL will execute it immediately. await or Promise.allSettled are not mechanisms to start asynchronous operations, they are mechanisms to wait for an operation that has already kicked off.
If you want to build an array of functions and not call them immediately, instead of:
const fetchObj = fetchURL(obj);
outputArray.push(fetchObj);
You probably just want:
outputArray.push(() => fetchURL(obj));
If you later on want to use Promise.allSettled, you could do this as such:
Promise.allSettled(outputArray.map(foo => foo());
Here's a cleaned up version of your code that also fixes more bugs:
for(const groupedRecord of groupedRecords) {
const fetchObjects = createFetchObjectArray(groupedRecord);
// Assuming you're doing something with fetchObjects after?
}
function fetchURL(obj) {
return fetch('http://localhost:8888/.netlify/functions/meta1', {
method: 'POST',
body: JSON.stringify(obj),
headers: { 'Content-Type': 'application/json' }
});
}
function createFetchObjectArray(records) {
return records.map(record => {
const obj = { "_id": record._id };
return () => fetchURL(obj);
});
}
I'm trying to write a small program that will ping internal addresses to check if a server is down.
The problem is that I cant get the timing right.
If I put a console.log() inside the for of loop it returns the objects I want but several times of cource. If I write a console.log after the for of loop, I only get an empty array, probably because the loop is not finished yet.I have tried to fix this in various ways but keep running into problems. I use node-cmd to send an http ping as normal pings only work against domains.
You can ignore my nightmare regex :)
It should just split the response into an array which is then pushed to object
var cmd = require('node-cmd');
const hosts = [
'https://adressone.com',
'https://adresstwo.com',
'https://adressthree.com',
'https://adressfour.com'
];
let results = [];
for (let host of hosts) {
cmd.run(`http-ping.exe ${host}`,
async function(err, data, stderr) {
const result = await data.split('>');
const resultDig = result[1].replace(/[^0-9\.]+/g, " ").replace(/2$/g, "").trim().split(' ')
results.push({
host: host,
status: resultDig[0],
bytes: resultDig[1],
time: resultDig[2],
});
}
);
}
console.log(results);
The result I would like in console.log(results):
[{
host: 'https://adressone.com',
status: '200',
bytes: '703',
time: '640'
},
{
host: 'https://adresstwo.com',
status: '200',
bytes: '703',
time: '640'
},
{
host: 'https://adressthree.com',
status: '200',
bytes: '703',
time: '640'
},
{
host: 'https://adressfour.com',
status: '200',
bytes: '703',
time: '640'
}
]
The best approach for this question will be by using Promises in JavaScript.
An example for this implementation.
async function parseResult() {
const hosts = [
"https://adressone.com",
"https://adresstwo.com",
"https://adressthree.com",
"https://adressfour.com",
];
const promises = [];
for (let host of hosts) {
const response = new Promise(function (resolve, reject) {
setInterval(async () => {
resolve({
status: "Success",
});
}, 1000);
});
promises.push(response);
}
const finalResult = await Promise.all(promises);
return finalResult;
}
parseResult().then((res) => console.log(res));
OR
async function parseResult() {
const hosts = [
"https://adressone.com",
"https://adresstwo.com",
"https://adressthree.com",
"https://adressfour.com",
];
const promises = hosts.map(
(host) =>
new Promise(function (resolve, reject) {
setInterval(async () => {
resolve({
status: "Success",
});
}, 1000);
})
);
const finalResult = await Promise.all(promises);
return finalResult;
}
parseResult().then((res) => console.log(res));
A Pseudo code for your question will be like below
var cmd = require("node-cmd");
async function parseResult() {
const hosts = [
"https://adressone.com",
"https://adresstwo.com",
"https://adressthree.com",
"https://adressfour.com",
];
let promises = [];
for (let host of hosts) {
const response = cmd.run(
`http-ping.exe ${host}`,
async function (err, data, stderr) {
const result = await data.split(">");
const resultDig = result[1]
.replace(/[^0-9\.]+/g, " ")
.replace(/2$/g, "")
.trim()
.split(" ");
// Returning a promise here
return new Promise(function (resolve, reject) {
resolve({
host: host,
status: resultDig[0],
bytes: resultDig[1],
time: resultDig[2],
});
});
}
);
promises.push(response);
}
// promises array will hold a list of promises now
// Await till all the promises are resolved and that will be your final result
const finalResult = await Promise.all(promises);
return finalResult;
}
parseResult().then((res) => console.log(res));
Explanation: Here the parseResult function loops through an array hosts and will run an async operation against each nodes in hosts array. The result of this operation is a Promise, so your final promises array will be holding a list of promises. Once all this promises are resolved, you will get your final result. You can detect when all your promises are resolved by using await Promise.all(promises)
I'd suggest to use node-cmd-promise. I removed the splitting:
const cmd = require('node-cmd-promise')
const hosts = [
'https://adressone.com',
'https://adresstwo.com',
'https://adressthree.com',
'https://adressfour.com',
]
async function main() {
const results = []
for (const host of hosts) {
const result = await cmd(`echo ${host}`)
// Insert logic here
const resultDig = [result.stdout, 'foo', 'bar']
results.push({
host,
status: resultDig[0],
bytes: resultDig[1],
time: resultDig[2],
})
}
console.log(results)
}
main()
I usually work with other programming languages, need to implement a bit of node.js code though, which I am entirely new to: For now, I just want the result of my azure function app to be actually dependent on me calling the api. I put the HTTP call into a promise and am waiting for the result:
module.exports = async function (context, req) {
context.res = {
body: {
"data": [{
"value": "start"
}]
}
};
await callapi(context);
};
function callapi(context){
var options = {
host: 'jsonplaceholder.typicode.com',
port: 443,
path: '/todos/1',
method: 'GET'
};
var p1 = new Promise(
function(resolve, reject) {
callback = function(httpres) {
var str = '';
response.on('error', function (err) {
context.res = {body: {"data": [{"value": "error"}]}};
});
httpres.on('data', function (chunk) {
str += chunk;
});
httpres.on('end', function () {
resolve(str);
});
}
https.request(options, callback).end();
}
);
p1.then(function(reqhtml) {
context.res = {
body: {
"data": [{
"value": "it worked"
}]
}
};
})
}
My expectiation for this was that it would - depending on if the server could be reached - either return (a context with) the value "it worked" or "error", however it doesnt wait for the promise and just returns "start".
How do I wait for the async function in Azure? I do not have code outside of this; this function is only called via another API, from where I can only manipulate results in a restrained way with a graphical user interface. Is there a way to force node.js to wait inside this function?
I've cleaned up your code a bit.
module.exports = async function (context, req) {
const value = await callapi();
context.res = {
body: {
data: [{
value
}]
}
};
};
// this function does not need any parameters,
// it's sole job is to make a https request to a static endpoint
// and return a value based on wether there was an error or not
function callapi(){
var options = {
host: 'jsonplaceholder.typicode.com',
port: 443,
path: '/todos/1',
method: 'GET'
};
return new Promise(function(resolve, reject) {
const req = https.request(options, res => {
let str = "";
res.on('data', function(chunk) {
str += chunk;
});
res.on('end', function() {
resolve(str);
});
});
res.on('error', reject);
req.end();
})
.then(() => "it worked")
.catch(() => "error");
}
For now, I just want the result of my azure function app to be actually dependent on me calling the api.
Since your callapi does not return anything await callapi() will await undefined and this will resolve in the next tick. (Basically, immediately after all current syncronous code has been executed and long before the Server could have sent any data back to you)
2nd: Mutating objects is frowned upon, because it's (mentally) hard to keep track of all the places that are potentially affected by this change; therefore it's dangerous. better return a copy with the changes.
3rd: keep it simple callapi does nothing where it would need to know anything about the context
The NPM library deasync solves the problem:
module.exports = async function (context, req) {
var uri = <uri>;
var source = get_source_at(uri)
context.res = { body: { "data": [{"value": source}] } };
};
function get_source_at(uri){
var request = require("request");
var deasync = require("deasync");
var source;
request({ uri:uri, headers: <headers>}
, function (error, response, body) {
source = body;
});
while(source === undefined) { //wait until async HTTPS request has finished
deasync.runLoopOnce();
}
return source;
}
I'm having some trouble with a function that returns before ajax call from for loop ends. I do several ajax call which I get the result from and use them on my then chain.
Here is my code
const delay = t => new Promise(resolve => setTimeout(resolve, t));
(async () => {
await delay(timeout);
let results: boolean[] = [];
for (let i = 0; i < times; i++) {
await this.ajaxService.postWithData("/api/v1/..",
arg,
(data) => {
results[i] = this.checkStep(data);
},
() => {
});
}
return results; // This returns before for loop containing ajaxServces calls ends
})().then((results) => {
// Do some things here using `results`
});
postWithData
public request = (options: Options, successCallback: Function, errorCallback?: Function): void => {
var that = this;
$.ajax({
url: options.url,
type: options.method,
data: options.data,
cache: false,
success: function (d) {
successCallback(d);
},
error: function (d) {
if (errorCallback) {
errorCallback(d);
return;
}
}
});
}
I've checked SO answers, e.g. https://stackoverflow.com/a/40329190/3264998
your request wrapper is not great and unfortunately Aaron's isn't much better. I haven't used jQuery much in recent years, but I think it has Promise-based APIs now too. Either way you'll want something generic that basically gives you a "promisified" version of $.ajax so you can work with await -
const defaultOpts =
{ method: 'GET', cache: false }
const request = (opts = {}) =>
new Promise
( (resolve, reject) =>
$.ajax({ ...defaultOpts, ...opts })
.done((req, status, res) => resolve(res))
.fail((req, status, err) => reject(err))
)
You haven't provided a Minimum, Complete, Verifiable Example (MVCE) so it makes it difficult help you. We don't know about times or checkStep so some guesses were made about your intentions. Something like this might help get your wheels turning again -
const main = async () =>
{ const steps =
[ request ("/api/v1/something..")
, request ("/api/v1/another..")
, request ("/api/v2/andthis..")
]
const res =
await Promise.all(steps)
console.log(res)
// [ <result1>, <result2>, <result3> ]
// I don't know what your checkStep does
// but something like this might work
res.forEach(r => this.checkStep(r))
// otherwise
// const checked =
// res.map(r => this.checkStep(r))
// ...
return res
}
main()
.then(res => console.log("all results", res))
// [ <result1>, <result2>, <result3> ]
.catch (e => ...)
If one request is dependent on another, putting the requests in an array and then calling Promise.all is not a great fit. In the example below we query all the posts for a particular author. The fictional API we're querying asks for the author's username but we only know the author's id. In this case, we look up the author's username first, then we can query the posts by username -
const authorById = id =>
request({ url: '/authors', data: { id } })
const postsByAuthor = username =>
request ({ url: '/posts', data: { author: username } })
const main = () =>
{ const author =
await authorById (10)
// { id: 10, username: alice, email: alice#email.lol }
// this request depends on the result of the first request
const posts =
await postsByAuthor (author.username)
// [ { postId: 9, title: "hello world" }, { postId: 11, ... }, ... ]
// ...
}
Something like this should work
public request = (options: Options, successCallback: Function, errorCallback?: Function): Promise => {
return new Promise( (resolve, reject) => {
var that = this;
$.ajax({
url: options.url,
type: options.method,
data: options.data,
cache: false,
success: function (d) {
resolve(successCallback(d));
},
error: function (d) {
if (errorCallback) {
reject(errorCallback(d));
}
}
})};
}
Also, you specified a return type for your function, would you be using TypeScript? Not sure if Promise return type is valid. But the idea is that you need to return a promise.
Im am doing nodeschool exercises , the
This problem is the same as the previous problem (HTTP COLLECT) in
that you need to use http.get(). However, this time you will be
provided with three URLs as the first three command-line arguments.
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.
in other words , i am to register 3 http.get request , and print data recieved from it in order.
I am trying to do it with promises = another get request wont be called untill the first on didnt end.
My code looks like this
var http=require("http");
var collect=[];
var dat=[];
for( var i = 2 ; i < process.argv.length;i++){
collect.push(process.argv[i]);
}
function chainIt(array,callback){
return array.reduce(function(promise,item){
return promise.then(function(){
return callback(item)
})
},Promise.resolve())
}
function getIt(item){
return http.get(item,function(response){
response.on("data",function(data){
dat.push(data);
})
})
}
chainIt(collett,function(item){
return getIt(item)
})
}).then(function(){
collect.forEach(function(x){
console.log(x);
})
})
But i actually print no data = i fail the exercise.
I do not see any bug here , but im just starting with promises and node. Where is the mistake?
For educational purposes, I recently wrote a wrapper for the http and https modules that uses native Promises. That said, I recommend using a library, such a request; that makes things simpler, has unit test coverage, as is maintained by the open source community. Also, my wrapper does a naive string concatenation with the response chunks, which I'm not convinced is the most performant way of building up the response body.
FYI: this requires Node.js 4 or above, although the methodology is pretty much the same in Node 0.x.x.
'use strict';
const http = require('http');
const url = require('url');
module.exports = {
get(url) {
return this._makeRequest('GET', url);
},
_makeRequest(method, urlString, options) {
// create a new Promise
return new Promise((resolve, reject) => {
/* Node's URL library allows us to create a
* URL object from our request string, so we can build
* our request for http.get */
const parsedUrl = url.parse(urlString);
const requestOptions = this._createOptions(method, parsedUrl);
const request = http.get(requestOptions, res => this._onResponse(res, resolve, reject));
/* if there's an error, then reject the Promise
* (can be handled with Promise.prototype.catch) */
request.on('error', reject);
request.end();
});
},
// the options that are required by http.get
_createOptions(method, url) {
return requestOptions = {
hostname: url.hostname,
path: url.path,
port: url.port,
method
};
},
/* once http.get returns a response, build it and
* resolve or reject the Promise */
_onResponse(response, resolve, reject) {
const hasResponseFailed = response.status >= 400;
var responseBody = '';
if (hasResponseFailed) {
reject(`Request to ${response.url} failed with HTTP ${response.status}`);
}
/* the response stream's (an instance of Stream) current data. See:
* https://nodejs.org/api/stream.html#stream_event_data */
response.on('data', chunk => responseBody += chunk.toString());
// once all the data has been read, resolve the Promise
response.on('end', () => resolve(responseBody));
}
};
EDIT: I only just realised you're new to Promises. Here's an example of how to use this wrapper:
'use strict';
const httpService = require('./httpService'); // the above wrapper
// get one URL
httpService.get('https://ron-swanson-quotes.herokuapp.com/v2/quotes').then(function gotData(data) {
console.log(data);
});
// get multiple URLs
const urls = [
'https://ron-swanson-quotes.herokuapp.com/v2/quotes',
'http://api.icndb.com/jokes/random'
];
/* map the URLs to Promises. This will actually start the
* requests, but Promise.prototype.then is always called,
* even if the operation has resolved */
const promises = urls.map(url => httpService.get(url));
Promise.all(promises).then(function gotData(responses) {
/* responses is an array containing the result of each
* Promise. This is ordered by the order of the URLs in the
* urls array */
const swansonQuote = responses[0];
const chuckNorrisQuote = responses[1];
console.log(swansonQuote);
console.log(chuckNorrisQuote);
});
Using Promise.all is the most efficient solution for this. You could also use async/await like below to solve this.
const http = require('http');
const bl = require('bl');
async function httpGet(url) {
return new Promise((resolve, reject) => {
http.get(url, response => {
response.setEncoding('utf8');
response.pipe(bl((err, data) => {
if (err) {
reject(err);
}
resolve(data.toString());
}));
});
});
}
async function main() {
const data1 = await httpGet(process.argv[2]);
const data2 = await httpGet(process.argv[3]);
const data3 = await httpGet(process.argv[4]);
console.log(data1);
console.log(data2);
console.log(data3);
}
main();
I don't think this exercise was meant to be solved with promises. I found my old exercice folder, this is how I did it without promises or extra libraries:
var http = require('http');
var urls = process.argv.slice(2);
// counts the number of requests done
var done = 0;
// stores the requests result
var result = [];
// this will be called by each http.get and they will provide their index
function callback(index, data) {
result[index] = data;
done++;
// all requests are done, log everything
if (done == urls.length) {
result.forEach(console.log);
}
}
function processUrl(url, index) {
var finalData = '';
http.get(url, function(response) {
response.setEncoding('utf8');
response.on('data', function(data) {
finalData += data;
});
response.on('error', console.error);
response.on('end', function() {
// console.log(finalData);
callback(index, finalData);
})
});
}
urls.forEach(processUrl);
Don't worry, you'll have enough promises to play with in the promise-it-wont-hurt workshop.
A bit late to the party here :)
Unfortunately none of the answers here uses the builtin util module in node.
Here is how to promisify http.get using util module and it is working correctly with typescript:
import util from "util";
const httpGetPromisified = util.promisify(
(url: string, cb: (err: any, result: IncomingMessage) => void) =>
http.get(url, (res) => cb(null, res))
);
// with promise.then
httpGetPromisified("http://www.google.com").then((res) => {
// res here has type http.IncomingMessage
console.log(res.statusCode);
});
// with async/await
const res = await httpGetPromisified("http://www.google.com");
console.log(res.statusCode);
Here's my solution after going through this thread:
var http = require('http');
var bl = require('bl')
promises = [
promiseLoad(process.argv[2]),
promiseLoad(process.argv[3]),
promiseLoad(process.argv[4])
];
Promise.all(promises).then(function(res) {
for(i=0; i<promises.length; i++) {
console.log(res[i]);
}
});
function promiseLoad(url) {
var body = '';
return new Promise(function(resolve, reject) {
http.get(url, function (response) {
response.setEncoding('utf8');
response.pipe(bl(function (err, data) {
resolve(data.toString())
}))
})
});
}
Here's the official solution in case you want to compare notes:
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(err)
}
results[index] = data.toString()
count++
if (count === 3) {
printResults()
}
}))
})
}
for (var i = 0; i < 3; i++) {
httpGet(i)
}
const http = require('http');
const urls = process.argv.slice(2);
let callCount = 0;
const cb = (res) => {
res.setEncoding('utf8');
let rawData = '';
res.on('data', (chunk) => {
rawData += chunk.toString();
});
res.on('end', () => {
callCount += 1;
console.log(rawData);
if (callCount < urls.length) {
getData(urls[callCount]);
}
});
res.on('error', (error) => {
console.log(error);
});
};
const getData = (url) => {
http.get(url, cb);
};
getData(urls[callCount]);
Here's how I did it:
async myFunc = function {
let url = 'http://your.data/file';
let promise = new Promise((resolve, reject) => {
var data = '';
https.get(url, res => {
res.on('data', chunk => { data += chunk })
res.on('end', () => {
resolve(data);
})
})
});
let result = await promise; // wait until the promise resolves
doStuffWithResult(result);
};
One of the method is by using 'Q' library.
First create function that will hit URL and return promise
var Q = require('q);
function getIt(item){
return http.get(item,function(response){
return Q.resolve(response); // Return response
OR
return Q.resolve(error); // Return error
})
})
}
var urls = ['url1','url2','url3']; // list of urls
Q.spread(urls.map(getIt))
.then(function(res1,res2,res3){
// res1 is response for url1 and on
//Once all calls are finished you will get results here
});