HTML5 FileReader每个循环都会崩溃浏览器 - 优化大型目录

时间:2013-01-25 19:13:42

标签: jquery html5 loops filesystems filereader

我有一个代码可以获取用户的本地目录,然后为它在目录中找到的每个mp3文件打开一个文件阅读器对象。有时这可能超过1,000个文件。如何优化此代码以使其不会崩溃浏览器?它适用于最多包含200-300个文件的目录,但是在控制台日志中没有任何错误会导致浏览器崩溃。任何建议将不胜感激。 这是我的代码的jsFiddle页面的链接: http://jsfiddle.net/X6BZe/

filecount变量用于尝试将文件拆分为10个组,并使用settimeout函数将它们分开,但这似乎不是很有效。我尝试了它,但它仍然使浏览器崩溃。

这是我的代码的主要部分,其余部分只是帮助检索ID3标记的jDataView代码。

$(document).ready(function(){
$("#file-input").on("change", function(e){
var thefiles = e.target.files;
var filecount = 0;
$.each(thefiles, function(i, item){
    if(item.type == "audio/mp3"){
        var reader = new FileReader();
        reader.onload = function() {
            var dv = new jDataView(this.result);
            if (dv.getString(3, dv.byteLength - 128) == 'TAG') {
                var title = dv.getString(30, dv.tell());
                var artist = dv.getString(30, dv.tell());
                var album = dv.getString(30, dv.tell());
                var year = dv.getString(4, dv.tell());
                $("#thelist").append(title + " - " + artist + " - " + album + " - " + year + "<br />");
            } 
            else {// no ID3v1 data found.
                var title = "????";
                var artist = "????";
                var album = "????";
                var year = "????";
            }
            dv = "";
        }
        reader.readAsArrayBuffer(thefile);
    }
    filecount += 1;
    if(filecount == 10){
        setTimeout(function(){}, 1000);         
        filecount = 0;
    }
});
});

1 个答案:

答案 0 :(得分:1)

看起来问题是您最终打开并阅读的文件数量很多......

当我重构它时(请参阅下面的相当丑陋的代码,但是有一堆控制台日志记录,这样你就可以看到会发生什么),这样它就不会试图爆破并打开整个数组的FileReaders,它会顺序处理 lot 比你想要的慢(因为它必须读取每个文件以获得最后的ID3标签)它不会崩溃(我也将dv和filereader设置为“”之后处理...不确定它是否有助于内存管理,但似乎保持chrome分配上升得非常高。)

您可以通过管理保持打开的FileReader的数量来提高顺序解决方案的吞吐量(例如,有一个 n 读取器池,并且一旦完成,就将其提供给下一个项目在列表和实验中找到连接数,吞吐量和稳定性之间的权衡

可能有更优雅的解决方案;)

$(document).ready(function(){
    $("#file-input").on("change", function(e){
    var thefiles = e.target.files;

  var i = 0;

  //    $.each(thefiles, function(i, item){
//      var thefile = item;

console.log("Start process");
process(i);
console.log("------> All Done <---------");

function process(wf) {
    thefile = thefiles[wf];
        if (thefile.type == "audio/mp3") {
            console.log("Read " + thefile.name + " " + thefile.type);

            var reader = new FileReader();
                reader.onload = function() {
                    console.log("********** Processing ");
                var dv = new jDataView(this.result);
                if (dv.getString(3, dv.byteLength - 128) == 'TAG') {
                    var title = dv.getString(30, dv.tell());
                    var artist = dv.getString(30, dv.tell());
                    var album = dv.getString(30, dv.tell());
                    var year = dv.getString(4, dv.tell());
                    $("#thelist").append(title + " - " + artist + " - " + album + " - " + year + "<br />");
                } 
                else {// no ID3v1 data found.
                    var title = "????";
                    var artist = "????";
                    var album = "????";
                    var year = "????";
                }
                dv = "";
                reader = "";
                console.log("Processed");
                    i++
                            if (i<thefiles.length) {
                    process(i);
                } else {
                    return
                }
            }

            reader.readAsArrayBuffer(thefile);
        } else {
            console.log("Skip " + thefile.name + " " + thefile.type);
                i++
                             if (i<thefiles.length) {

                              process(i);
                } else {
                    return
                }
        }


  } // end of process

//  });
});
});