Returning a variable from closure
How can I get the return value of that.whatever back from the closure? Instead of:
this.setCanvas = function(files){
var numItems = files.length - 1;
this.items = {};
var i = 0;
for(i=0;i<=numItems;i++)
{
var file = files[i];
var reader = new FileReader();
reader.onload = (function(i) {
return function(e) {
var something = that.whatever();
items[i] = something;
};
开发者_JAVA技巧 })(i);
reader.readAsDataURL(file);
}
console.log(items);
}
I need items[i] defined. If I console.log items[i] outside of the closure it is undefined.
The problem isn't the closure; it's the callback. Whatever needs to use the value of that.whatever
needs to be executed in the callback.
You can augment your code to keep track of the number of files loaded. This way, when the last file has been loaded, you can invoke an ultimate completion handler:
this.setCanvas = function(files) {
var numItems = files.length - 1;
var itemsLoaded = 0; // Initialize to zero
var items = [];
var i = 0;
for(i=0;i<=numItems;i++) {
var file = files[i];
var reader = new FileReader();
reader.onload = (function(i) {
return function(e) {
var something = that.whatever();
items[i] = something;
if(++itemsLoaded == numItems) {
// At this point all files will have been loaded.
allLoaded();
}
};
})(i);
reader.readAsDataURL(file);
}
function allLoaded() {
// Now we can analyze the results
console.log(items);
}
}
I also changed items
to be an Array
instead of an Object
.
Also if you want to be a little more clever, you could decrement numItems
and check for zero instead of creating a new itemsLoaded
variable.
There are a couple things you need to change here. First set this.items to an array. Next assign this to self so it can be referenced in the closure. Next assign the something to self.items[i] instead of items[i]. Finally use this.items in the console.log
this.setCanvas = function(files){
var self = this;
var numItems = files.length - 1;
this.items = [];
var i = 0;
for(i=0;i<=numItems;i++)
{
var file = files[i];
var reader = new FileReader();
reader.onload = (function(i) {
return function(e) {
var something = that.whatever();
self.items[i] = something;
};
})(i);
reader.readAsDataURL(file);
}
console.log(this.items);
}
精彩评论