Reputation: 1468
I was cleaning up my code and ran into a little trouble with callbacks, specifically getting the correct values to output when a callback is called. Could some explain to me why the following code spits out something that I'm not expecting and a possible solution without having to put in another parameter of i to the run() function, or is passing in i to know my index upon calling the callback the only way to do this?
for (var i in dls) {
run(dls[i][0], dls[i][1], function(isTrue){
if (isTrue) {
// Do true stuff here
} else {
console.log("Value is: " + dls[i][3])
}
});
}
Calling run() actually has the correct inputs inside, but upon that function calling the callback and going into the else statement, dls[i][3] spits out the same value i times.
I've tried putting different scopes around (run()) and such but to no avail and can't seem to wrap my head around this.
Thanks
EDIT:
If I wanted to split it up into a separate function, how would I do it?
var run = function(cb){
setTimeout(function() {
cb(false)
}, 3000);
}
for (var i in dls) {
run(dls[i][0], dls[i][1], (function(index) {
return extraction
})(i));
}
function extraction(isTrue){
if (isTrue) {
// stuff
} else {
console.log("Nothing changed in " + dls[i][3])
}
}
Here dls[i][3] is still incorrect and prints the same value 3 times.
Upvotes: 0
Views: 186
Reputation: 5538
In regards to the edit / second question, assuming this is what you wanted to do:
// note that I changed the function signature of `run`
var run = function(val1, val2, cb) {
setTimeout(function() {
cb(false);
}, 3000);
};
// note the `wrapper` here
for (var i in dls) {
run(dls[i][0], dls[i][1], wrapper(i));
}
// this is the same as what the IIFE is doing,
// just with an external function instead
function wrapper(scopedIndex) {
// return a function to be used as the callback for `run`
return function extraction(isTrue) {
if (isTrue) {
// stuff
}
else {
// use the scoped index here
console.log("Nothing changed in " + dls[scopedIndex][3]);
}
}
}
Take a look at function makeExitCallback(i)
in the other linked question, as well. It directly relates to what's going on here.
You should post what's in dls
as well, just to make it easier to run your snippets locally.
Upvotes: 1
Reputation: 869
You have fallen into the traditional "loop trap"
When it comes time for your callback to run i
is now a different value.
What you can do is cache that value in another wrapper function:
for (var i in dls) {
run(dls[i][0], dls[i][1], (function (currentIndex) {
return function(isTrue){
if (isTrue) {
// Do true stuff here
} else {
console.log("Value is: " + dls[currentIndex][3])
}
};
})(i));
}
Upvotes: 2