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

正如您所指出的,您的代码存在两个独立的问题,并且它们都有些相关。首先,ttt 正在全球范围内进行修改。问题是您要在修改发生之前检查它们。我怀疑这client.getMatchHistory()是在进行异步调用。不能保证第二个for循环中的所有异步操作都将在您执行第三个for循环时执行,您在其中读取数组。

第二个问题是范围之一,但你的问题不是全局范围。由于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

首先,所有全局变量都是有效的“窗口”对象字段,因此您可以使用 window.ttt 来确保您使用的是全局变量而不是本地变量。该代码应该可以工作,那么您是否在开发人员工具中尝试过?调试器对此类变量的存在有何看法?

至于变量 i:当然,你可以使用它,但最好在本地使用它,定义 'var i;' 在函数的顶部不破坏全局命名空间。

于 2012-12-26T06:48:15.647 回答
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不能参考,当计数超过最后执行的请求时,您运行应该在最后执行的函数请求完成。iafterloop()i_final

注意:请尽可能少地使用全局变量,在你的代码中你使用了全局变量,i没有任何理由

于 2012-12-26T06:49:57.703 回答