Reputation: 1019
Below is the code I'm working on. I'm wondering why, when I change the variable ttt
in the function, the changes do not stay outside of the function? I've declared it as var ttt = new Array;
at the very top.
Also, why can't I use the variable i
in the function?
code:
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]);
});
Upvotes: 0
Views: 216
Reputation: 2916
As you pointed out, there are two separate problems with your code, and they're both somewhat related. First, ttt
is being modified globally. The problem is that you're checking for the modifications before they happen. I suspect that client.getMatchHistory()
is making an asynchronous call. There's no guarantee that all the asynchronous operations in the second for
loop will be done executing by the time you execute the third for
loop, where you read the array.
The second problem is one of scope, but it's not global scope that's your problem. Since client.getMatchHistory()
is asynchronous, the callbacks will be called once the loop is done executing. Once the loop's done executing i
will have a value of 10
. Likely this is not what you intended. You need to create a callback generating function, that takes the value of i
, and returns a function that can be used as a callback. Like this:
function make_callback(i) {
return function(err, result) {
// The body of your callback in here
};
}
And then you should use it like this in the body of the loop:
client.getMatchHistory(434582, make_callback(i))
This will capture the value of i
in the current iteration and the generated callback will use that value when executed. That should fix your problem with i
.
Upvotes: 2
Reputation: 8049
The client.getMatchHistory
probably asynchronous request, you expect that after loop, you will have filled ttt
array, to acheive this you have to make a handler which run after last loop step:
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();}
});
}
in the sample, i_final
counts done requests, they can be done in random order, due to async, so you can't refer to i
when deciding to run afterloop()
, when i_final
count to more than last executed request, you run function that should be executed after last request is done.
Note: please use global vars as less as possible, in your code you used global i
without any reason
Upvotes: 0
Reputation: 5780
First of all, all globals variables are effectively 'window' object fields, so you can use window.ttt to be sure you are using global variables instead of local. This code should work, so did you try it in developer tool? what does debugger say about presence of such variable?
As for variable i: sure, you can use it, but it better to use it locally, defining 'var i;' on the top of the function to not spoil global namespace.
Upvotes: 0