0

附件是有问题的代码。

var http = require("http");
var i = 0;

var hostNames = ['www.1800autoland.com','www.youtube.com','www.1800contacts.com'];

for(i;i<hostNames.length;i++){
    var options = {
        host: hostNames[i],
        path: '/'
    };
    http.get(options, function(res){
        console.log("url: " + hostNames[i]);
        console.log("status: " + res.statusCode);

        for(var item in res.headers){
            if(item == "server"){
                console.log(item + ": " + res.headers[item]);
            }
            if(item == "x-powered-by"){
                console.log(item + ": " + res.headers[item]);
            }
            if(item == "x-aspnet-version"){
                console.log(item + ": " + res.headers[item]);
            }
        }
        console.log("\n");
    })
};

我有一个 URL 数组,我来咨询该站点的问题是,在我的代码中,hostNames[i] 没有将第 n 个(或在这种情况下为“i”)索引显示为字符串。控制台中的输出总是“未定义”。我尝试过 String()、toString() 和许多不同的方法,但均无济于事。有人能指出我正确的方向吗?我需要做什么转换?

4

3 回答 3

3

这是由于异步而发生的典型闭包问题。当您的回调触发时, 的值i将始终为hostNames.length.

要在 的值附近修复它i

http.get(options, (function(res) { // '(' before function is optional, I use it to indicate immediate invocation
    return function (i) {   // this is the closed value for i
        console.log("url: " + hostNames[i]);
        console.log("status: " + res.statusCode);
        // .. etc
    };
}(i))); // immediate invocation with i

意识到使用这样的闭包的重要一点是,您正在创建许多匿名函数,而不仅仅是一个。每个函数都绑定到它自己的值i


避免编写这些奇怪代码的最简单方法是不for直接使用循环,而是使用map函数。像:

function array_map(array, callback) {
    var i, len = array.length;
    for (i = 0; i < len; i += 1) {
        callback(i, array[i]);
    }
}

这使得您可以自动关闭 的值i。您的循环将如下所示:

array_map(hostNames, function(i, hostname) { // i and hostname have the closed value
    // .. etc
});
于 2013-02-25T17:30:11.197 回答
1

这是关闭问题,试试这个:

(function (i) {
http.get(options, function(res){
    console.log("url: " + hostNames[i]);
    console.log("status: " + res.statusCode);

    for(var item in res.headers){
        if(item == "server"){
            console.log(item + ": " + res.headers[item]);
        }
        if(item == "x-powered-by"){
            console.log(item + ": " + res.headers[item]);
        }
        if(item == "x-aspnet-version"){
            console.log(item + ": " + res.headers[item]);
        }
    }
    console.log("\n");
})
})(i);
于 2013-02-25T17:35:32.050 回答
0

您应该使用 .get(i) 方法来检索项目。正如其他人所说,您不需要初始化数组中的计数器。

于 2013-02-25T17:26:56.603 回答