简体   繁体   English

在对象内部使用FileReader

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM