Q.all:
Returns a promise that is fulfilled with an array containing the fulfillment value of each promise, or is rejected with the same rejection reason as the first promise to be rejected.
or Q.allSettled:
Returns a promise that is fulfilled with an array of promise state snapshots, but only after all the original promises have settled, i.e. become either fulfilled or rejected.
So you'd do three things:
Modify processData and possibly your call to MongoDB so that you end up with processData returning a promise for the asynchronous operation. (Apologies, I'm not familiar with MongoDB. Alnitak says that with modern versions, if you don't supply a callback, MongoDB returns a promise (nice!). Otherwise, this question and its answers may help with returning a promise for a callback-based API.)
Use map instead of forEach to get an array of the resulting promises.
Use Q.all or Q.allSettled on that array of promises.
If User.find returns a promise when no callback is specified, #1 looks something like this:
var processData = function(userIDSelected) {
return User.find(
{_id: userIDSelected},
{gender: 1, country:1}
).then(function(req, foundUser) { // <== Check these args with the MongoDB docs!
return processUserInfo(foundUser[0]['gender']);
});
};
If not, you can do it yourself with Q.defer:
var processData = function(userIDSelected) {
var d = Q.defer();
User.find(
{_id: userIDSelected},
{gender: 1, country:1},
function(req, foundUser) {
processUserInfo(foundUser[0]['gender']);
d.resolve(/*...data could go here...*/); // You'd use d.reject() if there were an error
});
return d.promise;
};
Then here's what 2 and 3 look like:
Q.all(found.map(function(item) { // Or Q.allSettled
return processData(item);
}))
.then(...)
.catch(...);
If processData only ever uses its first argument (ignoring any extra ones), you can ditch the intermediary function:
Q.all(found.map(processData)) { // Or Q.allSettled
.then(...)
.catch(...);
...but only if processData ignores extra args, as map will pass it three (the value, its index, and the array).