How can you synchronize this process using nodejs?

I need to iterate on an array, for each item I apply an operation by calling an HTTP call.

The difficulty is that i need to syncronize this process in order to call a callback after the loop (containing the array after all the operation executed by the HTTP call).

Let's consider this short example:

 function customName(name, callback) {
   var option = {
        host:'changename.com',
        path: '/'+name,
        headers: { 'Content-Type': 'application/json'  },
        port: 80,
        method:'POST'
    };

    var req = http.request(option, function(res) {
        var output = "";
        res.on('data', function (chunk) {
            output += chunk;
        });

        res.on('end', function() {
            var obj = JSON.parse(output);
            callback(obj.res);
        });
    });

    req.on('error', function(e) {
        console.error(e.message);
    });

    req.end();
}

function changeNames(OldNames, callback) {
  var Res = [];
  for (name in OldNames) {
    customName(OldNames[name], function(new_name) { Res.push(new_name); });
  });
  callback(Res);
}

var Names = ['toto', 'tata', 'titi'];
changeNames(Names, function(Names) {
    //...
});

Here the loop is over before the first HTTP call, so the Res array is empty.

How can we synchronize this execution?

I know it's not very good to synchronize treatments in nodejs. Do you think it would be better to communicate the names one by one with the client and not building an array?

You can use async.map for that. You pass it your list of names, it will run the getOriginalName function (which you mistakenly called customName, I think) for each name and gather the result, and in the end it will call a function with an array of results:

var http  = require('http');
var async = require('async');

function getOriginalName(name, callback) {
  var option = {
    host:'changename.com',
    path: '/'+name,
    headers: { 'Content-Type': 'application/json'  },
    port: 80,
    method:'POST'
  };

  var req = http.request(option, function(res) {
    var output = "";
    res.on('data', function (chunk) {
      output += chunk;
    });

    res.on('end', function() {
      var obj = JSON.parse(output);
      callback(null, obj.res);
    });
  });

  req.on('error', function(e) {
    callback(e);
  });

  req.end();
}

function changeNames(OldNames, callback) {
  async.map(OldNames, getOriginalName, callback);
}

var Names = ['toto', 'tata', 'titi'];
changeNames(Names, function(err, NewNames) {
  console.log('N', NewNames);
});