Your quoted code doesn't do what you've listed, you probably lost something simplifying it for the question.
This code would have the effect you're describing, though:
for(j in groups){
doSomething(function() {
// Callback for `doSomething`
console.log(j, somefunction(groups[j]));
});
}
Note that now I'm creating a function (a callback for whatever doSomething does), not just calling one.
The reason that happens is that the function being created has an enduring reference to the j variable (and everything else in the execution context), not a copy of it as of when the function was created. It's called a closure over that execution context. So your loop runs, a series of calls to doSomething start a series of things, and then later when the callbacks are called, j is 3 and so it's the same for all of them.
The usual solution is to create functions that close over something that won't change before they get called, like this:
for(j in groups){
doSomething(makeCallback(j));
}
function makeCallback(jarg) {
return function() {
console.log(jarg, somefunction(groups[jarg]));
};
}
Now, we're using jarg in our callback, rather than j. Because jarg is part of the context of the call to makeCallback, it doesn't change between when we create the function and when it's called later.
Another way you can bind data to functions is to use Function#bind (which effectively creates a closure in the background), which is an ES5 feature available in NodeJS because the V8 engine has it. Here's how that would look:
for(j in groups){
doSomething(function(jarg) {
// Callback for `doSomething`
console.log(jarg, somefunction(groups[jarg]));
}.bind(this, j)); // <== Note the bind
}
or less confusingly (and quite possibly more efficiently):
for(j in groups){
doSomething(handler.bind(this, j));
}
function handler(jarg) {
// Callback for `doSomething`
console.log(jarg, somefunction(groups[jarg]));
}
More about closures: