0

私は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 を使用したいのですが、うまくいきません。

4

1 に答える 1

3

ここでの問題はi、非同期コールバック内の switch ステートメントで参照していることです。これを行うと、関数の作成時に 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);
    }
});
于 2013-08-08T04:55:38.953 に答える