Search code examples
node.jsnode-async

Node array of function using variables from enclosing scope


I am trying to do dns.reverse() on a list of ip using async.parallel().

The code is as follows:

var functions = [];
for (var i = 0; i < data.length; i++) {
    var ip = data[i].ip;
    var x = function(callback) {
        dns.reverse(ip, (err, hostnames) => {
            if (err) {
                log.error("Error resolving hostname for [" + ip + '] ' + err);
                return callback(null, err);
            }

            callback(null, hostnames);
        });
    };

    functions.push(x);
}

async.parallel(functions, (err, results) => {
    for(var i = 0; i < data.length; i++) {
        data[i]['hostnames'] = results[i];
    }

    handler(null, data);
});

What is happening is dns.reverse() is getting called with the same ip (the last one in data array) for all the calls. May be I am doing something wrong. Can somebody explain what is my mistake?


Solution

  • Thanks to @apokryfos I got a hint. To get the code working I just need to use let instead of var while declaring ip.

            var functions = [];
            for (var i = 0; i < data.length; i++) {
                let ip = data[i].ip;
                var x = function(callback) {
                    dns.reverse(ip, (err, hostnames) => {
                        if (err) {
                            log.error("Error resolving hostname for [" + ip + '] ' + err);
                            return callback(null, err);
                        }
    
                        callback(null, hostnames);
                    });
                };
    
                functions.push(x);
            }
            async.parallel(functions, (err, results) => {
                for(var i = 0; i < data.length; i++) {
                    data[i]['hostnames'] = results[i];
                }
    
                handler(null, data);
            });
    

    For anybody interested in understanding following might be helpful: How do JavaScript closures work?