2017-02-15 21 views
0

私は現在、電子を使って練習中ですが、私はJavaScriptで非常に新しく、私は完全に困惑しています。array.lengthは0ですが、配列に要素があります

function getPaths() { 
     var dirPath = document.getElementById("mdir").innerHTML; 
     var filePaths = []; 
     fs.readdir(dirPath, function(err, dir) { 
     for(var i = 0, l = dir.length; i < l; i++) { 
      var filePath = dir[i]; 
      filePaths.push(dirPath + "/" + filePath); 
     } 
     }); 
     console.log(filePaths); 
     console.log(filePaths.length); 
    } 

dirPathで定義されたディレクトリの中に見えるようになっている、それはをループし、そのディレクトリ内のすべてのファイルのフルパスを取得します。私は、次のコードがあります。それを配列に追加してから、一番下には配列をコンソールに記録し、その後に配列の長さを記録します。 何が私を困惑させるのは、そのコードが与えられたとき、アレイは期待通りにコンソールにログを記録しますが、コンソールは長さとしてゼロを記録します。私の現在の考え方は、スコープと何か関係があるということですが、それは実行中の関数の上の配列のfilePathsという配列を宣言しているので意味がありません。私が何かを見逃していない限り。誰かが間違っていることを指摘できますか?

答えて

4

readdirは非同期です。すぐに結果を得ることはできません。コールバック内にfilePathsを記録する必要があります。コンソールが値を表示する唯一の理由は、展開時にコンソールがアレイを評価するためです。

左の小さな矢印を押すと、右側のiボックスにマウスを置きます。コンソールは配列への参照を保持しているので、ユーザーが配列を展開すると、現在の値が何であるかが表示されます。しかし、filePaths.lengthを記録すると、readdirはまだ読み終えていないので、配列は空です。なぜなら、あなたは0を得るからです。しかし、コンソールを開いて矢印を押すと、readdirはすでに読み込まれており、コンソールは現在の値を表示します配列の(それが満たされた後)。

enter image description here

例:(ないソリューションが、本当に何が起こっているのかを理解するための)

試してみて、このコードを実行すると起こるか見て:ここでは

var arr = []; 
setTimeout(function() { 
    arr.push(1, 2, 3); 
}, 5000); 
console.log(arr.length); 
console.log(arr); 

配列長さは両方とも配列が塗りつぶされる前に記録されます。配列は5秒後に塗りつぶされます。したがって、出力は0array[]になります。今度は配列に大量のデータが含まれている可能性があるため、ユーザーが配列を展開するまで、コンソールはそのデータを表示しません。だから、コンソールが何をするのかは、展開された矢印を押すまで配列の参照を保持することです。 5秒前に配列を展開すると、配列が空である(まだ塗りつぶされていない)ことがわかります。 5秒経過するまで待ってからそれを広げると、それが満たされていることがわかります!

ご理解くださいますようお願い申し上げます。

+1

ように私は、応答時間がディレクトリの内容 – MaxZoom

+0

に基づいて大幅に異なる可能性があるので 'setTimeout'機能を使用することをお勧めしません意味@ MaxZoom私は解決策として 'setTimeout'を提案しませんでした!私は問題の非同期性を強調するために 'setTimeout'を使って分かりやすい例を使ってOPの問題を説明しました! –

+1

だから、もし私がこの権利を持っていれば、値を得られない理由は、readdirが非同期であるからです。その結果、console.log()は配列が構築される前に完了し、結果として0を返します。 – Taira

2

ジャスト@イブラヒム・mahrirの答えに拡大して、彼らはこの

function getPaths() { 
    var dirPath = document.getElementById("mdir").innerHTML; 
    var filePaths = []; 
    fs.readdir(dirPath, function(err, dir) { 
     for (var i = 0, l = dir.length; i < l; i++) { 
      var filePath = dir[i]; 
      filePaths.push(dirPath + "/" + filePath); 
     } 
     console.log(filePaths); 
     console.log(filePaths.length); 
    }); 
} 
関連する問題