0

以下は私が取り組んでいるコードです。関数内の変数を変更するtttと、変更が関数の外にとどまらないのはなぜですか? 私はそれをvar ttt = new Array;一番上に宣言しました。

iまた、関数で変数を使用できないのはなぜですか?

コード:

  client.on('connection', function()
    {
        var sss;
        var aaa;

            console.log('Connected');

        for (i = 0 ; i < 120 ; i++)
            ttt[i] = 0;

        for (i = 0 ; i < 9 ; i++)
        {
                client.getMatchHistory(434582, function(err, result)        
            {
                sss = JSON.stringify(result);
                var myObject = eval('(' + sss + ')');
                console.log (myObject.object.data[i].object.value);

                ttt[myObject.object.data[i].object.value]++;
            });

        }

            for (i = 0 ; i < 120 ; i++)
                console.log ("Record" + i + " Successes: " + ttt[i]);

    });
4

3 に答える 3

2

ご指摘のとおり、コードには 2 つの別個の問題があり、どちらも多少関連しています。まず、グローバルに変更されていますttt 問題は、変更が発生する前に変更をチェックしていることです。client.getMatchHistory()非同期呼び出しを行っていると思われます。配列を読み取るfor3 番目のループを実行するまでに、2 番目のループのすべての非同期操作の実行が完了するという保証はありません。for

2 番目の問題はスコープの 1 つですが、問題はグローバル スコープではありません。は非同期であるためclient.getMatchHistory()、ループの実行が完了するとコールバックが呼び出されます。ループの実行iが完了すると、値は になり10ます。おそらく、これは意図したものではありません。の値を受け取り、コールバックとして使用できる関数を返すコールバック生成関数を作成する必要があります。iこのような:

function make_callback(i) {
  return function(err, result) {
    // The body of your callback in here
  };
}

そして、ループの本体で次のように使用する必要があります。

client.getMatchHistory(434582, make_callback(i))

これによりi、現在の反復での値が取得され、生成されたコールバックは実行時にその値を使用します。これで問題が解決するはずiです。

于 2012-12-26T07:04:34.607 に答える
0

client.getMatchHistoryおそらく非同期のリクエストです。ループの後、ttt配列がいっぱいになると予想されます。これを実現するには、最後のループステップの後に実行されるハンドラーを作成する必要があります。

var afterloop=function() {
    for (var i = 0 ; i < 120 ; i++)
       console.log ("Record" + i + " Successes: " + ttt[i]);
}
for (var i = 0 ; i < 120 ; i++)
        ttt[i] = 0;

var i_final=0;
for (var i = 0 ; i < 9 ; i++)
        {   
            var i=i;   //localise i
            client.getMatchHistory(434582, function(err, result)        
            {
                i_final++;
                sss = JSON.stringify(result);
                var myObject = eval('(' + sss + ')');
                console.log (myObject.object.data[i].object.value);

                ttt[myObject.object.data[i].object.value]++;
                if (i_final>8) {afterloop();}
            });

        }

サンプルでは、i_final​​完了したリクエストをカウントします。非同期のため、ランダムな順序で実行できるため、i実行を決定するときに afterloop()参照できませんi_final。最後に実行されたリクエストよりも多くカウントすると、最後に実行する必要がある関数を実行しますリクエストが行われます。

注:グローバル変数をできるだけ少なく使用してください。コードでは、i何らかの理由でグローバルを使用しました

于 2012-12-26T06:49:57.703 に答える
0

まず第一に、すべてのグローバル変数は事実上「ウィンドウ」オブジェクト フィールドであるため、window.ttt を使用して、ローカルではなくグローバル変数を使用していることを確認できます。このコードは機能するはずなので、開発者ツールで試してみましたか? そのような変数の存在についてデバッガーは何と言っていますか?

変数 i: は確かに使用できますが、「var i;」を定義してローカルで使用することをお勧めします。グローバル名前空間を台無しにしないように関数の上部に。

于 2012-12-26T06:48:15.647 に答える