2017-12-03 69 views
0

最近,我一直在尝试在html中包含某个文件夹中的所有文件。我决定创建一个批处理文件来创建一个包含所有文件列表的文本文件,然后在javascript函数中使用生成的文本文件来填充表格。构建Javascript函数会导致页面加载时出现错误

功能showDownloads被称为在页面加载,并引发以下错误:

Uncaught TypeError: Cannot read property 'length' of undefined 
    at showDownloads (script.js:8) 
    at onload ((index):9) 

但是,如果我从控制台运行showDownloads(),它正确生成表没有抛出任何错误。

var downloadPath = "../builds/dev-versions/"; 
var downloads; 

function showDownloads() { 
    getData(); 
    var table = document.getElementById('downloadTable'); 

    for (var i = 0; i < downloads.length; i++) { //Error happens here 
    var row = document.createElement('tr'); 
    for (var j = 0; j < downloads[i].length; j++) { 
     var cell = document.createElement('td'); 
     var file = document.createElement('a'); 
     file.setAttribute('href', downloadPath + downloads[i][j]); 
     file.setAttribute('download', downloads[i][j]); 
     file.innerHTML = downloads[i][j]; 

     cell.appendChild(file); 
     row.appendChild(cell); 
    } 
    table.appendChild(row); 
    } 
} 

function getData() { 
     var xmlhttp; 

     if (window.XMLHttpRequest) { 
      xmlhttp = new XMLHttpRequest(); 
     } 
     else { 
      xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); 
     } 

     xmlhttp.onreadystatechange = function() { 
      if (xmlhttp.readyState == 4) { 
      var lines = xmlhttp.responseText; 

      intoArray(lines); 
      } 
     } 

     xmlhttp.open("GET", "devFiles.txt", true); 
     xmlhttp.send(); 
} 

function intoArray (lines) { 

    var lineArr = lines.split('\n'); 
    lineArr.pop(); 

    downloads = new Array(lineArr.length/2); 

    var j = 0; 
    for (var i = 0; i < lineArr.length; i += 2) { 
    downloads[j] = [lineArr[i], lineArr[i + 1]]; 
    j++; 
    }; 
} 

为什么在第一次调用期间数组downloads被视为未定义?

为什么不是通过致电getData创建的?

+1

它被创建....它只是异步....因为你不使用'promises'和'.then'你的代码在你的getData()实际获取数据之前继续。在稍后的时间点(当你打开控制台并键入内容时,它就在那里,因此它可以工作 – Dellirium

+0

Ahhh ...我不知道这可能是一个问题,因为我在编程方面相对缺乏经验,我认为'getData ()'在默认情况下会在继续之前完成,我会看看'promises'和'.then',谢谢 – IsenfireLDC

+0

'getData'确实完成了,但由于你写'getData'的方式,这个函数的结果在'downloads'变量中不存在,也就是说,用于处理HTTP请求的事件处理函数'onreadystatechange'就是因为它的名字在readystate改变之后就被解雇了,这并不一定会在你之前尝试访问'downloads'变量,事实上在你尝试访问它之前它肯定不会触发,这就是为什么要重视同步和异步之间的差异 – Dellirium

回答

1

我想这是一个异步问题,for循环不会等待getData完成,因此在页面加载时,下载仍然是空的,但是当您在控制台中尝试它时,下载将完成并存储下载的数据。由于它是一个全局变量,因此当您在控制台中运行它时,它可能实际上正在处理以前数据提取中的数据。

相关问题