简体   繁体   English

未捕获的 DOMException:无法在“FileReader”上执行“readAsDataURL”:该对象已在忙于读取 Blob。(...)

[英]Uncaught DOMException: Failed to execute 'readAsDataURL' on 'FileReader': The object is already busy reading Blobs.(…)

I am working on this for the past 6 hours, and I am unable to figure this out.我在过去的 6 个小时里一直在研究这个,但我无法弄清楚。

I am trying to create a website, in which I choose a folder of images and I show them in my document.我正在尝试创建一个网站,在其中选择一个图像文件夹并将它们显示在我的文档中。 I get the first image to show, and then I get the following error in my console.我得到了要显示的第一张图像,然后在控制台中出现以下错误。

Uncaught DOMException: Failed to execute 'readAsDataURL' on 'FileReader': The object is already busy reading Blobs.(…)未捕获的 DOMException:无法在“FileReader”上执行“readAsDataURL”:该对象已在忙于读取 Blob。(...)

I believe the issue is caused due to my for loop because the filereader is asynchronous.我相信这个问题是由于我的 for 循环引起的,因为文件阅读器是异步的。 But I need to loop through the whole array for this, so what am I doing wrong?但是我需要为此遍历整个数组,所以我做错了什么?

I load the files ("will check to make sure I get only images later"), into an array, and then I read each file one at a time.我将文件(“稍后将检查以确保我只获取图像”)加载到一个数组中,然后我一次读取每个文件。 Before breaking down my code to functions I did everything in a single function and it works!在将我的代码分解为函数之前,我在一个函数中完成了所有工作,并且可以正常工作! I included the HTML + the original and current JS code.我包含了 HTML + 原始和当前的 JS 代码。 Thank you for taking the time to see this.感谢您抽出时间看到这一点。

HTML 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 Original: 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 Current: 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);
        }
      }
    };
  }

The reason why your code fails is that you are using the same reader variable on each subsequent loop iteration.您的代码失败的原因是您在每个后续循环迭代中使用相同的阅读器变量。

When Javascript parses your code, what happens is that all variables get moved to the top of the function, so your parsed code looks something like this:当 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);
      }
    }

You could avoid this error quite simply by just moving all the logic inside the anonymous function like so:您可以简单地通过移动匿名函数中的所有逻辑来避免此错误,如下所示:

    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]);
      }
    }

Now you are using a unique reader variable for each file iteration.现在您正在为每个文件迭代使用唯一的读取器变量。 Note also that this could be simpler if you just did:另请注意,如果您只是这样做,这可能会更简单:

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

Or just used the let variable (that way you will use a different FileReader every time):或者只是使用let变量(这样你每次都会使用不同的FileReader ):

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

      for (let 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);
      }
    }

The for loop could be written easier with es6 leaving you with 2 less variables使用 es6 可以更轻松地编写 for 循环,从而减少 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);
      }
    }

But if you want it super easy, why not just skip the FileReader altogether and avoid all functions & callbacks with URL.createObjectURL ?但是如果你想要它超级简单,为什么不完全跳过FileReader并避免使用URL.createObjectURL所有函数和回调? Using createObjectURL you save CPU de/compiling the file to/from base64:使用createObjectURL可以节省 CPU 对 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);
      }
    }

the Problem occured because I was trying to use the same reader for every image.出现问题是因为我试图为每个图像使用相同的阅读器。 Moving var reader = new FileReader();移动var reader = new FileReader(); into the loop (ShowLoadedImages function), solved the issue and showed all the images like it was supposed to.进入循环(ShowLoadedImages 函数),解决了这个问题,并像它应该的那样显示了所有的图像。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法在&#39;FileReader&#39;上执行&#39;readAsDataURL&#39;:对象已经忙于读取Blob - Failed to execute 'readAsDataURL' on 'FileReader': the object is already busy reading Blobs 未捕获的 DOMException:无法在“FileReader”上执行“readAsDataURL” - Uncaught DOMException: Failed to execute 'readAsDataURL' on 'FileReader' FileReader错误:对象已经忙于读取Blob - FileReader error: The object is already busy reading Blobs FileReader JS引发对象正在忙于读取Blob - FileReader JS throws The object is busy reading a blobs Angular.js:未捕获的TypeError:无法在“ FileReader”上执行“ readAsDataURL”:参数1的类型不是“ Blob” - Angularjs : Uncaught TypeError: Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob' 未捕获的类型错误:无法在“FileReader”上执行“readAsDataURL”:参数 1 的类型不是“Blob” - Uncaught TypeError: Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob' 拖放:未捕获类型错误:无法在“FileReader”上执行“readAsDataURL”:参数 1 不是“Blob”类型 - Drag and Drop: Uncaught TypeError: Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob' 有时会:无法在“FileReader”上执行“readAsDataURL”:参数 1 不是“Blob”类型 - Sometimes getting: Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob' 未捕获的 DOMException:无法在“Window”上执行“postMessage”:无法克隆对象 - Uncaught DOMException: Failed to execute 'postMessage' on 'Window': An object could not be cloned 类型错误:无法在“FileReader”上执行“readAsDataURL”:参数 1 的类型不是“Blob” - TypeError: Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM