2016-10-31 50 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函數)中,解決了問題並顯示了所有圖像。

相關問題