2016-10-31 6 views
0

저는 지난 6 시간 동안이 작업을하고 있습니다.잡히지 않은 DOMException : 'FileReader'에서 'readAsDataURL'을 실행하지 못했습니다. 객체가 이미 BLOB를 읽는 중입니다. (...)

나는 이미지 폴더를 선택하고 내 문서에 표시하는 웹 사이트를 만들려고합니다. 첫 번째 이미지가 표시되고 콘솔에 다음 오류가 표시됩니다.

는 catch되지 않은 예외 : DOMException는 '을 FileReader'에 'readAsDataURL'을 실행하지 못했습니다. 개체가 이미 바쁜 독서 물방울입니다 (...) 문제가 인해 발생

내가 믿는 내 루프의 파일 리더이기 때문이다 비동기. 하지만 이것을 위해 전체 배열을 반복해야합니다. 그래서 내가 뭘 잘못하고 있습니까?

파일을로드하고 ("이미지 만 나중에 확인합니다") 어레이에로드 한 다음 각 파일을 한 번에 하나씩 읽습니다. 코드를 기능에 적용하기 전에 모든 기능을 단일 기능으로 수행했으며 작동합니다! 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> 

자바 스크립트 원본 :

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

자바 스크립트 현재 :

나는 모든 이미지에 대해 같은 리더를 사용하려고했기 때문에 문제가 발생
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

코드가 동일한 리더를 사용하는 이유는 동일한 리더 변수를 사용하기 때문입니다.
당신의 구문 분석 코드가이

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) 리더를 사용하고 있습니다.그냥

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

을했던 아니면 그냥 루프 쉽게 작성할 수

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

let 변수 (다른 FileReader 때마다 사용하는 방법)을 사용하는 경우 참고 또한이 더 간단 할 수 있음 ES6으로이 개 덜 변수

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 모든 togeth을 반드시 당신을 떠나 어 및 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); 
    } 
} 
로/파일을 컴파일/createObjectURL 당신이 CPU 드를 저장하여 URL.createObjectURL 모든 기능을 & 콜백을 피하기
0

. var reader = new FileReader();을 루프 (ShowLoadedImages 함수)로 이동하여 문제를 해결하고 예상했던 것과 같은 모든 이미지를 보여주었습니다.

관련 문제