Reputation: 634
I know there are a ton of questions regarding callbacks, scope, and closures. I apologize in advance if this is a duplicate.
I have an each loop that calls a function that performs several async actions and then issues a callback. I'm losing scope (obviously) when the callback fires. What I've done is pass the item in the loop to the function and then I return it in the callback so I have the scope I need. Is that the best way to do this? I'm not looking for something overly complicated. I just want to make sure I'm not going to run into any "gotchas".
function doSomething(varA, varB, self, callback) {
// do a lot of ajax stuff
callback(varA + varB, self);
}
$.each( $('.selected'), function(i, item) {
doSomething('a', 'b', item, function(retVal, self) {
// process retVal and self
}
}
Upvotes: 1
Views: 212
Reputation: 91587
Since callback
is defined within the .each()
function, item
still is in scope by the time you get to your callback function. So, if doSomething()
never uses self
, you don't need to pass it. You can just reference item
:
function doSomething(varA, varB, callback) {
// do a lot of ajax stuff
callback(varA + varB);
}
$('.selected').each(function(i, item) {
doSomething('a', 'b', function(retVal) {
// process retVal and item
});
});
Now, if the callback were defined outside of .each()
, you'd have to do it the way you have it, passing item
to doSomething()
:
function doSomething(varA, varB, self, callback) {
// do a lot of ajax stuff
callback(varA + varB, self);
}
function doSomethingCallback(retVal, self) {
// process retVal and item
}
$('.selected').each(function(i, item) {
doSomething('a', 'b', item, doSomethingCallback);
});
Upvotes: 0
Reputation: 755259
The main "gotcha" people run into with ajax and loops is trying to reuse the iteration variable inside the function which executes later. For example
for (var i in col) {
$.ajax({
url: '...' + i + '.html',
success: function() {
console.log(i); // Why is i different???
}
});
}
This "gotcha" occurs because there is 1 instance of i
shared amongst all of the success
callbacks.
In your scenario though you have one i
for every "iteration" level. So this gotcha won't hit you.
Upvotes: 0
Reputation: 5086
If you don't need the element reference inside doSomething
, you can create a closure in this, slightly tidier way:
function doSomething(varA, varB, callback) {
// do a lot of ajax stuff
callback(varA + varB);
}
$.each( $('.selected'), function() {
var self = this;
doSomething('a', 'b', function(retVal) {
// process retVal and self
}
});
Upvotes: 1