I have the following model with a file reading function. However, the reading is done after the next piece of code. Why and how can I get it to return the read content of the file?
TreeContainer = Backbone.Model.extend({
elementCount: 0,
file: '',
object: {jj: "kk"},
type: "input",
parent: d3.select("#canvas"),
initialize: function () {
var result = this.readFile();
for (var i = 0; i < 200; i++) {
console.log(i); //this is resulted before the readFile content
}
},
readFile: function () {
var model = this;
// display text
if (this.get('file').name.endsWith(".json") || this.get('file').type === "application/json") {
var reader = new FileReader();
reader.onload = function (e) {
//parseJSON
var text = e.target.result;
var data = JSON.parse(text);
model.set('object', data);
console.log(data);
return data;
};
reader.readAsText(this.get('file'));
}
}
});
You have fallen for the async for loop problem
You can only loop over all files after you have read all the content Here is a example using Screw-FileReader
initialize: function(){
this.readFile().then(arr => {
for (let json of arr) {
console.log(json) //this is resulted before the readFile content
}
})
},
readFile: function() {
function isJSON(file) {
return file.name.toLowerCase().endsWith('.json') ||
file.type === 'application/json'
}
return Promise.all(
Array.from(input.files)
.filter(isJSON)
.map(file => file.json())
)
}
Alternetive is to wrap FileReader in a Promise
return new Promise(resolve => {
reader.onload = function (e) {
var text = e.target.result
var data = JSON.parse(text)
model.set('object', data)
resolve(data)
}
})
or send in a callback
initialize: function(){
this.readFile(json => {
json
})
},
readFile: function(resolve) {
resolve(data)
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.