node.js:函数外的变量

时间:2013-08-08 04:06:10

标签: javascript node.js

我是NodeJS的新手,我正在试图找出一些东西,但不幸的是,凭借我的知识,我无法找到相关信息。

基本上,我想使用另一个函数中的函数变量,该函数是主函数的子函数。

这是我的代码:

http.get(url, function(res) {
var body = '';

res.on('data', function(chunk) {
    body += chunk;
});

res.on('end', function() {
    var jsonResult = JSON.parse(body);
    for (var i=0;i<5;i++)
    {
        gameId = jsonResult.gameList[i].gameId;
        url = 'http://somesite.com/' + gameId + '/0/token';
        http.get(url, function(res) {
            var body = '';

            res.on('data', function(chunk) {
                body += chunk;
            });

            res.on('end', function() {
                jsonRes = JSON.parse(body);
                switch(i)
                {
                    case 0:
                        var elo0 = jsonRes.interestScore;
                        module.exports.elo0 = elo0;
                        break;
                    case 1:
                        var elo1 = jsonRes.interestScore;
                        module.exports.elo1 = elo1;
                        break;
                    case 2:
                        var elo2 = jsonRes.interestScore;
                        module.exports.elo2 = elo2;
                        break;
                    case 3:
                        var elo3 = jsonRes.interestScore;
                        module.exports.elo3 = elo3;
                        break;
                    case 4:
                        var elo4 = jsonRes.interestScore;
                        module.exports.elo4 = elo4;
                        break;

                }


        });
        }).on('error', function(e) {
            console.log("Got error: ", e);
        });

    }

});
}).on('error', function(e) {
  console.log("Got error: ", e);
});

请注意,我没有包含所有内容,只包含有问题的部分。 我想在交换机内部使用循环中的变量i,但它不起作用。

1 个答案:

答案 0 :(得分:3)

这里的问题是您在异步回调中的switch语句中引用i。当你这样做时,你不会在创建函数时获得i的值,而是在循环迭代结束时得到i的最终值。

有几种方法可以解决这个问题 - 两种方法都涉及在闭包中捕获i的当前循环值,以供稍后回调引用。

例如:

for (var i=0;i<5;i++)
{
    (function(idx) {
        gameId = jsonResult.gameList[idx].gameId;
        url = 'http://somesite.com/' + gameId + '/0/token';
        http.get(url, function(res) {
            ...

            res.on('end', function() {
                jsonRes = JSON.parse(body);
                switch(idx)
                {
                    case 0:
                      break;

                    ...
                }
            });
            ...
        });
    })(i);
}

这里,为循环中的每次传递创建一个匿名函数,并立即调用循环计数器i的当前值作为传入参数idx

另一种方法(如上面的注释中所述)是将循环的内部部分重构为一个单独的函数,并调用它传递所有必要的上下文:

function scoreHandler(jsonResult, idx) {
    var gameId = jsonResult.gameList[idx].gameId;
    var url = 'http://somesite.com/' + gameId + '/0/token';
    http.get(url, function(res) {
        ...

        res.on('end', function() {
            jsonRes = JSON.parse(body);
            switch (idx) {
               ...
            }
        });
    })
    .on('error', function(e) {
        console.log("Got error: ", e);
    });
}

您的重构循环看起来像:

res.on('end', function() {
    var jsonResult = JSON.parse(body);
    for (var i = 0; i < 5; i++) {
        scoreHandler(jsonResult, i);
    }
});