2016-12-24 86 views
0

我在和Node玩,有一個奇怪的問題(對我來說很奇怪)。自從我做了Javascript以來,已經有很長的一段時間了,所以問題很可能在我面前凝視。Javascript(節點)將對象推入陣列

我遍歷目錄中的JSON文本文件列表,解析每個文件中的文本。它正確地移動目錄;當我檢查console.log時,每個對象顯示正確。

但是,當我試圖將它推到一個數組上時,沒有任何反應,大小在循環結束時保持爲1。這感覺就像一個範圍問題。

感謝您的任何建議。

app.get("/people/:value1/metrics/:value2", function(req, res) { 
    var value1 = req.params.value1; 
    var value2 = req.params.value2; 
    var personPath = "people/" + value1 + "/" + value2; 
    var content; 
    var data = []; 

    fs.readdir(personPath, function(err, files) { 
    if(err) { 
     console.log(err); 
    } 
    files.forEach(function (file, index) { 
     content = fs.readFileSync(personPath + '/' + file); 
     console.log(JSON.parse(content)); //Correctly outputs the object. 
     content = JSON.parse(content); 
     data.push(content); 
    }); 
    }); 
    console.log(data.length); //Always 0. 
    res.send(data); 
}); 
+0

這看起來像異步代碼,將您送入READDIR –

+0

謝謝你的建議所有,這是偉大的。 –

回答

0

fs.readdir是一個異步執行離子。您的console.log(data.length)正在fs.readdir執行完成之前執行。

這也意味着您的res.send也過早執行。

同步方式

執行考慮使用fs.readdirSync,如果你想繼續操作的順序,在你的代碼是相同的:

app.get("/people/:value1/metrics/:value2", function(req, res) { 
    var value1 = req.params.value1; 
    var value2 = req.params.value2; 
    var personPath = "people/" + value1 + "/" + value2; 
    var content; 
    var data = []; 

    fs.readdirSync(personPath).forEach(function(file, index) { 
     content = fs.readFileSync(personPath + '/' + file); 
     console.log(JSON.parse(content)); //Correctly outputs the object. 
     content = JSON.parse(content); 
     data.push(content); //I'm sure this is push references that are destroyed when out of scope. 
    }); 
    console.log(data.length); //Always 0. 
    res.send(data); 
}); 

更多fs.readdirSync這裏: https://nodejs.org/api/fs.html#fs_fs_readdirsync_path_options

異步執行

您應該花些時間來了解有關異步執行的更多信息。這篇文章有一個很好的解釋:How does Asynchronous Javascript Execution happen? and when not to use return statement?

如果您在fs.readdir的範圍內移動的console.logres.send,這應該解決您的問題:

app.get("/people/:value1/metrics/:value2", function(req, res) { 
    var value1 = req.params.value1; 
    var value2 = req.params.value2; 
    var personPath = "people/" + value1 + "/" + value2; 
    var content; 
    var data = []; 

    fs.readdir(personPath, function(err, files) { 
    if(err) { 
     console.log(err); 
    } 
    files.forEach(function (file, index) { 
     content = fs.readFileSync(personPath + '/' + file); 
     console.log(JSON.parse(content)); 
     content = JSON.parse(content); 
     data.push(content); 
    }); 
    console.log(data.length); //placed within the scope of fs.readdir 
    res.send(data); 
    }); 
}); 

編輯:還有一兩件事要注意的是.forEach是不是異步的。在句法上,fs.readdir.forEach都相似,但.forEach是一種阻止方法。這意味着每一次迭代都會在下一行執行之前完成。因此,在之後console.logres.send,.forEach應該產生期望的結果。

更多.forEach是一個阻塞方法在這裏:JavaScript, Node.js: is Array.forEach asynchronous?

0

您需要了解異步執行,並把此塊:

console.log(data.length); 
res.send(data); 

權之前fs.readdir

1

最後的支架由於它是異步函數代碼:

files.forEach(function (file, index) { 
     content = fs.readFileSync(personPath + '/' + file); 
     console.log(JSON.parse(content)); //Correctly outputs the object. 
     content = JSON.parse(content); 
     callback(content);  
    }); 

callback(content) 
{ 
    data.push(content); 
}