2016-10-31 22 views
0

我正在为此工作6个小时,我无法弄清楚。未被捕获的DOMException:未能在'FileReader'上执行'readAsDataURL':该对象已经忙于读取Blob。(...)

我想创建一个网站,我在其中选择一个图像文件夹,然后将它们显示在我的文档中。我得到第一张图片,然后在控制台中出现以下错误。

未捕获抛出:DOMException:未能执行“readAsDataURL”上“的FileReader”:对象是已经忙于阅读的斑点(...)

我认为问题是由于引起了我的for循环,因为的FileReader是异步。但我需要循环遍历整个数组,所以我做错了什么?

我加载文件(“将检查以确保我以后只能得到图像”),放入数组中,然后每次读取一个文件。 在将我的代码分解为函数之前,我在一个函数中做了所有事情,并且它可以工作!我包含HTML +原始和当前的JS代码。 感谢您花时间看到这一点。

HTML

<!DOCTYPE html> 
<html> 
    <head> 
    <meta charset="utf-8"> 
    <title>Tiled Image Viewer</title> 
    <script src="js/tiv.js"></script> 
    <link rel="stylesheet" href="style.css"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 

    </head> 
    <body> 

    <div id="main-wrap"> 
     <form name="uploadForm"> 

     <input id="images" type="file" webkitdirectory mozdirectory directory name="myFiles" 
        onchange="readAndShowFiles();" multiple/> 

     <span id="list"></span> 
     </form> 

    </div> 

    </body> 
</html> 

的Javascript原文:

function readAndShowFiles() { 
var files = document.getElementById("images").files; 
for (var i = 0; i < files.length; i++) { 
    var file = files[i]; 
    // Have to check that this is an image though 
    // using the file.name TODO 
    var reader = new FileReader(); 
    // Closure to capture the file information. 
    reader.onload = (function(file) { 
    return function(e) { 
     // Render thumbnail. 
     var span = document.createElement('span'); 
     span.innerHTML = ['<img src="', e.target.result, 
     '" title="', escape(file.name), '">'].join(''); 
     document.getElementById('list').insertBefore(span, null); 
    }; 
    })(file); 
    // Read in the image file as a data URL. 
    reader.readAsDataURL(file); 
} 
} 

的Javascript电流:

function readAndShowFiles() { 
    console.log("Checkpoint2"); //test 
    var tiv = new tivAPI(); 
    var array = tiv.getLoadedImages(); 
    tiv.showLoadedImages(array); 
} 

function tivAPI(){ 
    var imagesarray = new Array(); 


    return{ 
     loadImages: function(){ 
     console.log("Loading Files"); //test 
     var files = document.getElementById("images").files; 
     for (var i = 0; i < files.length; i++) { 
      var file = files[i]; 
      // Have to check that this is an image though 
      // using the file.name TODO 
     } 
     console.log(files.length); //test 
     return files; 
     }, 
     getLoadedImages: function(){ 
     imagesarray = this.loadImages(); 
     console.log("Returning Files"); //test 
     console.log(imagesarray.length); 
     return imagesarray; 
     }, 
     showLoadedImages: function(elem){ 
     console.log("Showing Files"); //test 
     var files = elem; 
     var reader = new FileReader(); 
     // Closure to capture the file information. 
     for (var i = 0; i < files.length; i++) { 
      var file = files[i]; 
      reader.onload = (function(file) { 
      return function(e) { 
       // Render thumbnail. 
       var span = document.createElement('span'); 
       span.innerHTML = ['<img src="', e.target.result, 
       '" title="', escape(file.name), '">'].join(''); 
       document.getElementById('list').insertBefore(span, null); 
      }; 

      })(file); 
     // Read in the image file as a data URL. 
     reader.readAsDataURL(file); 
     } 
     } 
    }; 
    } 

回答

2

你的代码使用相同的阅读器的原因是因为你使用相同的阅读器变量。
什么JavaScript的剂量所有的变量被移到顶部,这样您解析的代码看起来是这样的

function readAndShowFiles() { 
    var files = document.getElementById("images").files; 
    var reader; 
    var file; 
    var i; 

    for (i = 0; i < files.length; i++) { 
    file = files[i]; 
    reader = new FileReader(); 
    reader.onload = (function(file) { 
     return function(e) { 
     var span = document.createElement('span'); 
     span.innerHTML = ['<img src="', e.target.result, 
      '" title="', escape(file.name), '">' 
     ].join(''); 
     document.getElementById('list').insertBefore(span, null); 
     }; 
    })(file); 
    reader.readAsDataURL(file); 
    } 
} 

你能避免它颇受只是将所有的逻辑里面的annonymes功能简单

function readAndShowFiles() { 
    var files = document.getElementById("images").files; 

    for (var i = 0; i < files.length; i++) { 
    // Closure to capture the file information. 
    (function(file) { 
     var reader = new FileReader(); 
     reader.onload = function(e) { 
     // Render thumbnail. 
     var span = document.createElement('span'); 
     span.innerHTML = ['<img src="', e.target.result, 
      '" title="', escape(file.name), '">' 
     ].join(''); 
     document.getElementById('list').insertBefore(span, null); 
     }; 
     // Read in the image file as a data URL. 
     reader.readAsDataURL(file); 
    })(files[i]); 
    } 
} 

现在您对每个文件都使用uniq阅读器。还要注意的是,这可能是simplier如果你只是做

array.from(files).forEach(function(file) { 
    // code 
}) 

或者只是使用的let变量(这样你将使用不同FileReader每次)

function readAndShowFiles() { 
    var files = document.getElementById("images").files; 

    for (var i = 0; i < files.length; i++) { 
    let file = files[i]; 
    let reader = new FileReader(); 
    reader.onload = function(e) { 
     // Render thumbnail. 
     var span = document.createElement('span'); 
     span.innerHTML = ['<img src="', e.target.result, 
     '" title="', escape(file.name), '">' 
     ].join(''); 
     document.getElementById('list').insertBefore(span, null); 
    }; 
    // Read in the image file as a data URL. 
    reader.readAsDataURL(file); 
    } 
} 

for循环可以写成更容易与ES6离开你少2个变量

function readAndShowFiles() { 
    var files = document.getElementById("images").files; 

    for (let file of files) { 
    let reader = new FileReader(); 
    reader.onload = function(e) { 
     // Render thumbnail. 
     var span = document.createElement('span'); 
     span.innerHTML = ['<img src="', e.target.result, 
     '" title="', escape(file.name), '">' 
     ].join(''); 
     document.getElementById('list').insertBefore(span, null); 
    }; 
    // Read in the image file as a data URL. 
    reader.readAsDataURL(file); 
    } 
} 

但如果你想超级容易为什么不干脆跳过FileReader所有磕磕碰碰呃,避免所有功能&回调与URL.createObjectURL使用createObjectURL您节省CPU DE /文件从的base64

function showFiles() { 
    var files = document.getElementById("images").files; 

    for (let file of files) { 
    let img = new Image; 
    img.src = URL.createObjectURL(file); 
    img.title = file.name; 

    document.getElementById('list').appendChild(img); 
    } 
} 
编译成/
0

问题的发生,因为我试图使用相同的读者对每个图像。 将var reader = new FileReader();移动到循环(ShowLoadedImages函数)中,解决了问题并显示了所有图像。

相关问题