2017-12-03 68 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完成,因此在頁面加載時,下載仍然是空的,但是當您在控制檯中嘗試它時,下載將完成並存儲下載的數據。由於它是一個全局變量,因此當您在控制檯中運行它時,它可能實際上正在處理以前數據提取中的數據。

相關問題