问题
Here's a simplification of my JS program. mylist is an array of strings and MyAsync is a function that takes an object and arranges for the supplied callback to be called at a later time.
for (var myindex = 0; myindex < mylist.length; myindex += 1) {
MyAsync(mylist[myindex], function () { alert(myindex); });
}
When there's ten items in mylist, the result is two alert messages each showing "10". Okay, it's clearly using the value of myindex after the loop finishes. So I make a slight change...
for (var myindex = 0; myindex < mylist.length; myindex += 1) {
var copyindex = myindex;
MyAsync(mylist[myindex], function () { alert(copyindex); });
}
Now, each alert shows "9".
How do I please arrange for the callback function to know what myindex was at the time MyAsync was invoked?
Asynchronously, billpg.
回答1:
Yeah, as the comments and not making functions in a loop for the reason you are experiencing.
We can use a recursive function instead :
var len = mylist.length;
function asyncLoop(index) {
MyAsync(mylist[index], function () {
if(index < len) {
asyncLoop(++index);
}
});
}
asyncLoop(0);
As comments , - firing them all off at the same time* ( *- quick as a loop can run ). and keeping track of the array count ...
function asyncDo(index) {
MyAsync(mylist[index], function () {
/* we have access to the array index here */
console.log(index);
});
}
for ( var i=0, len=mylist.length; i<len; ++i) { asyncDo(i); }
回答2:
You can use closures to do this: here is some code that I think demonstrates what you want, printing out 0 .. 9.
var funcs = [];
for(var i = 0; i < 10; i++){
funcs.push( (function(j){
return function(){
console.log(j);
};
})(i));
}
funcs.forEach(function(f){
f();
});
The idea is that in returning a function to be added to the list, the value of i is captured when that function was constructed from the parameter to the outer function.
Here's an SO post that helped me with this: JavaScript closures vs. anonymous functions
来源:https://stackoverflow.com/questions/22845270/how-can-i-write-a-js-callback-function-that-remembers-the-old-value-of-a-changin