2016-12-24 89 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); 
}