Synchronous loop with internal asynchronous calls Below I've written a simple version of what I'm attempting to accomplish. I'm new to asynchronous functions, so it's difficult to wrap my head around this. My goal is to wait for the loop to finish all the callbacks before console.log() runs, but I want all the callbacks inside the loop to be asynchronous, so they don't wait for calls to complete one after another, taking way too much time to complete. How would I write this, the loop to be synchronous (wait for all internal calls to complete) but the internal calls to be asynchronous?

Much appreciated!

var addressList = [];

for (var i = 0; i &lt; members.length; i++) {
  service.member.info({
    name: members[i],
    company: "Cerberus",
    // Callback function
    function(body) {
      addressList.push(body.address);
    }
  });
}

console.log(addressList);
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 &lt; 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 &lt; 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 &lt; members.length; i++) {
    operations.push(
      service.member.info({
        name: members[i],
        company: "Cerberus",
      })
    );
  }

  return (yield operations).map(body =&gt; 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 &lt; members.length; i++) {
    var body = await service.member.info({
      name: members[i],
      company: "Cerberus",
    });

    addressList.push(body.address);
  }

  return addressList;
}