You can do this manually with a counter along these lines (kind of messy):
function getAddresses(members, callback) {
var addressList = [];
var count = 0;
for (var i = 0; i < members.length; i++) {
service.member.info({
name: members[i],
company: "Cerberus",
}, function(body) {
addressList[i] = body.address;
count++;
if (count === members.length) {
callback(addressList);
}
});
}
}
There are also libraries for this sort of thing, like async:
var async = require('async');
function getAddresses(members, callback) {
async.map(members, function (member, callback) {
service.member.info({
name: member,
company: "Cerberus",
}, function (body) {
callback(null, body.address);
});
}, callback);
}
But promises are really the best option if you’re able to use them consistently throughout your project, with a library like bluebird:
var bluebird = require('bluebird');
// This only works if the callback is really (err, body)
bluebird.promisifyAll(service.member);
function getAddresses(members) {
return bluebird.map(members, function (member) {
return service.member.infoAsync({
name: member,
company: "Cerberus",
}).then(function (body) {
return body.address;
});
})
}
They could take some learning, but they’re the future of asynchronicity in JavaScript or something, since right now you can do this (or you could, if service.member.info
returned a promise) – note how close it is to your original loop:
var bluebird = require('bluebird');
var getAddresses = bluebird.coroutine(function* (members) {
var addressList = [];
for (var i = 0; i < members.length; i++) {
var body = yield service.member.info({
name: members[i],
company: "Cerberus",
});
addressList.push(body.address);
}
return addressList;
});
// or, to run the loop in parallel:
var getAddresses = bluebird.coroutine(function* (members) {
var operations = [];
for (var i = 0; i < members.length; i++) {
operations.push(
service.member.info({
name: members[i],
company: "Cerberus",
})
);
}
return (yield operations).map(body => body.address);
});
and one day, that might be simplified to this, but not yet:
async function getAddresses(members) {
var addressList = [];
for (var i = 0; i < members.length; i++) {
var body = await service.member.info({
name: members[i],
company: "Cerberus",
});
addressList.push(body.address);
}
return addressList;
}