简体   繁体   中英

asynchronous http.get callbacks in Node.js

In Node, I have this function snippet (greatly reduced from the actual function, so hopefully I didn't cut anything important out):

Driver.prototype.updateDevices = function() {
    for (ip in this.ips) {
        var curIp = ip;
        if (this.ips[curIp]) {  // in case this.ips[curIp] is set to undefined...
            http.get(
                {   host: curIp,
                    port: 80,
                    path: '/tstat'
                },
                function (res) {
                    var result = '';
                    res.on('data', function (chunk) {
                        result += chunk;
                    });
                    res.on('end', function () {
                        // Want to parse data for each ip, but
                        // curIp is always the last ip in the list
                    });
                }
            );
        };
    };
};

What I have is the "Driver" object, which contains "ips", an object containing a list of ip addresses, such as {"192.168.1.111":{stuff},"192.168.1.112":{stuff}}

Surely this is something very obvious that I'm overlooking, but I can't get it to work as expected. obviously, http.get() is called multiple times asynchronously. That is what I want; however, when the result is obtained and the "end" callback function is called, I can't access the "curIp" variable, which I want to contain the original ip address for the particular request being called back from. Instead the "curIp" variable always contains the last ip address in "this.ips". What am I missing? Any help would be greatly appreciated!

curIp is not scoped to the for loop, it's scoped to the enclosing updateDevices function so it's shared by all http.get calls and is overwritten each time through the for loop.

The typical way to fix this is to create an immediate function that creates its own scope which can capture each iteration's curIp value as a parameter to that function:

if (this.ips[curIp]) {
    (function(ip) {    // Immediate function with its own scope
        http.get(
            {   host: ip,
                port: 80,
                path: '/tstat'
            },
            function (res) {
                var result = '';
                res.on('data', function (chunk) {
                    result += chunk;
                });
                res.on('end', function () {
                    // ip is the captured ipCur here
                });
            }
        );
    })(curIp);   // Pass curIp into it as the ip parameter
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM