[英]Using FileReader inside object
I have an object which has a loadFile()
method that parses a wav file. 我有一个对象,该对象具有用于解析wav文件的loadFile()
方法。 I have been using a FileReader
outside the object and passing loadFile()
the ArrayBuffer
from the file read and letting it take over from there. 我一直在使用对象外部的FileReader
,并从读取的文件中将ArrayBuffer
加载到loadFile()
,然后从那里接管。 I want to have potentially many of the objects, so I'd like to wrap up a FileReader
inside the loadFile()
method so I don't have to deal with all the reader code outside for every object. 我想要潜在的许多对象,所以我想在loadFile()
方法中包装一个FileReader
,这样我就不必为每个对象处理所有外部的阅读器代码。 The problem is, I am not sure how this will work. 问题是,我不确定这将如何工作。 Here's a code visual: 这是直观的代码:
function MyObject() {
this.property;
this.anotherProp;
this.data = new Array(); // array to be filled with PCM data for processing
}
// pass a File object
MyObject.prototype.loadFile = function(file) {
var reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = function(event) {
var buffer = event.target.result;
// do lots of stuff with buffer and eventually fill up this.data[]
}
}
MyObject.prototype.doProcessing = function() {
// process this.data[]
}
var file; // a File object I grabbed from somewhere
var myObj = new MyObject();
myObj.loadFile(file);
myObj.doProcessing();
What will happen with loadFile()
here? 这里的loadFile()
会发生什么? Will loadFile
return before I have any data in myObj.data[]
? 在myObj.data[]
有任何数据之前, loadFile
返回吗? Or will it wait for reader.onload
to fire before returning? 还是会在返回前等待reader.onload
触发? If this is the wrong way to do this, how should I do it? 如果这是错误的方法,我应该怎么做? Aslo, what if I wanted loadFile()
to return false
if something inside reader.onload
fails? Aslo,如果我希望loadFile()
在reader.onload
内部失败时返回false
怎么办?
Possible Solution: http://jsfiddle.net/N6vnU/2/ 可能的解决方案: http : //jsfiddle.net/N6vnU/2/
Current Solution: I ended up moving the file parsing function out of the object into a web worker, and discovering FileReaderSync
. 当前解决方案:我最终将文件解析功能从对象中移到了Web worker中,并发现了FileReaderSync
。 Now I send the file off to the web worker and create an object with the results once they return. 现在,我将文件发送给网络工作者,并在返回结果后创建一个带有结果的对象。
Events in Javascript are asynchronous, so you have to assume that loadFile
will return before onload
runs (always assume for the worst case, because you cannot predict when an async call will be completed). Javascript中的事件是异步的,因此您必须假定loadFile
将在onload
运行之前返回(总是假定是最坏的情况,因为您无法预测异步调用何时完成)。
Your usual option is adding a callback parameter to loadFile
which you will call once onload
is done, or optionally integrating deferreds/futures if that's how you prefer to work. 通常的选择是将一个回调参数添加到loadFile
,一旦完成onload
,您将调用该参数,或者如果愿意的话,还可以选择集成延期/未来功能。
Also a hint: you need to call readAsArrayBuffer
after you assign the onload
handler, because again as it is async there's always the chance that you will miss this event if you first instruct the browser to read the file and then attach an event to it. 另外一个暗示:你需要调用readAsArrayBuffer
分配后 onload
处理程序,因为又因为它是异步总有那么你会错过这个事件,如果你第一次指示浏览器读取该文件,然后一个事件附加给它的机会。
Yes, the loadfile will return before the file is actually loaded. 是的,将在实际加载文件之前返回加载文件。 A nice approach could involve the use of promises. 一个好的方法可能涉及使用诺言。
For example, you could use the Q library. 例如,您可以使用Q库。 Here's a link to the API: https://github.com/kriskowal/q/wiki/API-Reference 这是指向API的链接: https : //github.com/kriskowal/q/wiki/API-Reference
If you already use jQuery, the $.Deferred object could be enough, even though I suggest you to use the promises offered by the Q library. 如果您已经使用jQuery,即使我建议您使用Q库提供的Promise,$ .Deferred对象也足够了。
The MyObject constructor could define a deferred (private would be ideal) to be resolved by the reader.onload
function. MyObject构造函数可以定义一个reader.onload
函数解析的延迟的(最好是私有的)。
Knowing so little about the real use of the MyObject instances, consider read the following as pseudo-code. 对MyObject实例的实际用途了解甚少,请考虑阅读以下内容作为伪代码。
function MyObject() {
this.def = $.Deferred(); //the deferred to be resolved when the content has been loaded
this.property;
this.anotherProp;
this.data = new Array(); // array to be filled with PCM data for processing
}
// pass a File object
MyObject.prototype.loadFile = function(file) {
var obj = this,
reader = new FileReader();
this.def = $.Deferred();
reader.readAsArrayBuffer(file);
reader.onload = function(event) {
var buffer = event.target.result;
obj.def.resolve();
// do lots of stuff with buffer and eventually fill up this.data[]
}
}
MyObject.prototype.doProcessing = function() {
this.def.done(function(){
// process this.data[]
console.log('resolved');
});
}
var file; // a File object I grabbed from somewhere
var x = new MyObject();
x.loadFile(file);
x.doProcessing(); //this would print 'resolved' when the file is loaded
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.