2017-12-03 23 views
0

最近、特定のフォルダ内のすべてのファイルを含むテーブルをhtmlで多少動的に作成しようとしています。私はバッチファイルを作成して、すべてのファイルのリストを含むテキストファイルを作成し、生成されたテキストファイルをJavaScript関数で使用してテーブルを埋めることにしました。テーブルビルドJavascript関数はページロード時にエラーを発生させます

機能showDownloadsは、ページのロード時に呼び出され、次のエラーがスローされます。

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

しかし、私はコンソールからshowDownloads()を実行した場合、それが適切にすべてのエラーをスローせずにテーブルを生成します。配列downloadsは、最初の呼び出し時に定義されていないと考えられているのはなぜ

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

getDataを呼び出すと、なぜそれが作成されないのですか?

+1

これはちょうど非同期です。あなたが 'promises'と' .then'を使わないので、あなたのコードは 'getData()'が実際にデータを取得する前に続きます。 – Dellirium

+0

ああ...私はこれが問題になるかもしれないと私は気づいていませんでしたプログラミングでは比較的経験の浅いので、私は 'getData ()はデフォルトで完了するでしょう。私は 'promises'と' .then'を見ていきます。ありがとう。 – IsenfireLDC

+0

'getData'は完了しましたが、あなたの' getData'この関数の結果は 'downloads'変数には存在しません。つまり、HTTP要求を処理するために使用されるイベントハンドラonreadystatechangeは、readystateが変更されたときに名前が発せられ、必ずしもあなたの前に来るとは限りません'downloads'変数にアクセスしようとしましたが、実際にアクセスしようとすると、実際には起動しませんので、同期と非同期の違いを突き止めることが重要です。 – Dellirium

答えて

1

私はそれが非同期の問題だと思いますが、forループはgetDataが終了するのを待たないので、ページのロード時にはまだ空ですが、コンソールで試してみるとダウンロードが完了して保存されますダウンロード中のデータこれはグローバル変数なので、前回のデータフェッチのデータを実際にコンソールで実行したときに処理している可能性があります。

関連する問題