Javascript HTML5文件API:加载太慢

Javascript HTML5文件API:加载太慢,javascript,html,filereader,Javascript,Html,Filereader,我不熟悉JavaScript和jQuery,而Google不会给出答案。我正在写一本在线电子书阅读器。这是一个库的代码,用户可以在其中输入多个epub文件,相关信息(如作者)应该显示在一个表中。为此,我需要解压缩ePub文件。作品完美无瑕。内容必须显示在动态创建的表中(因为我不知道文件的数量) 问题是for循环太快,创建的所有单元格中只包含名称和文件大小,在for循环完成文件读取器的加载后,执行文件读取器并将所有内容添加到最后一个单元格中。在此代码中,警报(“A”)发生的次数与警报(“B”)发生

我不熟悉JavaScript和jQuery,而Google不会给出答案。我正在写一本在线电子书阅读器。这是一个库的代码,用户可以在其中输入多个epub文件,相关信息(如作者)应该显示在一个表中。为此,我需要解压缩ePub文件。作品完美无瑕。内容必须显示在动态创建的表中(因为我不知道文件的数量)

问题是for循环太快,创建的所有单元格中只包含名称和文件大小,在for循环完成文件读取器的加载后,执行文件读取器并将所有内容添加到最后一个单元格中。在此代码中,警报(“A”)发生的次数与警报(“B”)发生之前输入的文件发生的次数相同。是否有某种方法可以让循环等待文件读取器的加载完成

function handleFileSelect(evt) {
var files = evt.target.files;
var rows = Math.ceil(files.length/3);
var a = 0;
var root = document.getElementById('mainTable');
var tab=document.createElement('table');
tab.style.textAlign = "center";
var row, cell;
var tbo=document.createElement('tbody');
for(var i  = 0; i != rows; i++)
{
  row=document.createElement('tr');
  for(var j = 0; (j < 3);j++)
  {
   cell = document.createElement('td');
   cell.height = "300px";
   cell.width = "300px"
   if(a <indexes.length)
   {
        var f = files[a];
        var str = f.name;
        str = str.substring(0, str.length - 5);
        str = "File Name: " + str;
        cell.appendChild(document.createTextNode(str));
        cell.appendChild(document.createElement('br'));
        str = "File Size: " + Math.round(f.size/1024) + " KB";
        cell.appendChild(document.createTextNode(str));
        cell.appendChild(document.createElement('br'));
        var reader = new FileReader();
        reader.onload = (function(theFile) 
        {
          return function(e) 
          {
              alert("B");
              var zip = new JSZip(e.target.result);
              $.each(zip.files, function (index, zipEntry) 
              {
                  cell.appendChild(document.createTextNode(zipEntry.name));
                  cell.appendChild(document.createElement('br'));
                  //row.appendChild(cell);
              });
          }
        })(f);
        reader.readAsArrayBuffer(f);
        alert("A");
        a++;
    }
    row.appendChild(cell);
  }
  tbo.appendChild(row);
}
tab.appendChild(tbo);
root.appendChild(tab);              
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
功能手柄文件选择(evt){
var files=evt.target.files;
var rows=Math.ceil(files.length/3);
var a=0;
var root=document.getElementById('mainTable');
var tab=document.createElement('table');
tab.style.textAlign=“中心”;
var行、单元格;
var tbo=document.createElement('tbody');
for(变量i=0;i!=行;i++)
{
行=document.createElement('tr');
对于(var j=0;(j<3);j++)
{
单元格=document.createElement('td');
cell.height=“300px”;
cell.width=“300px”

如果(a您的问题是,onload处理程序中使用的变量单元格将引用分配给外部循环中单元格的最后一个值。您可以通过将文件处理放在单独的函数中来解决此问题,该函数将创建它自己的作用域

function read_zip_file(f, cell) {
    var reader = new FileReader();
    reader.onload = (function(theFile) 
    {
      return function(e) 
      {
          alert("B");
          var zip = new JSZip(e.target.result);
          $.each(zip.files, function (index, zipEntry) 
          {
              cell.appendChild(document.createTextNode(zipEntry.name));
              cell.appendChild(document.createElement('br'));
              //row.appendChild(cell);
          });
      }
    })(f);
    reader.readAsArrayBuffer(f);
}
然后在外部循环中,您可以调用:

read_zip_file(f, cell);

是否有任何原因导致无法移动所有
单元格。appendChild(…)
语句到
onload
回调中?没有具体原因,但这无法解决问题,因为在调用onload函数之前,单元格的值已更改。可以通过创建一个临时变量来保存特定单元格来解决此问题。使用像Ali Gangji这样的函数可以工作。很好。然后您应该接受它为zip创建一个单独的函数是可行的。隐式创建一个临时单元格变量是解决方案,使用函数是最好的方法。