Javascript(Node)将对象推送到数组

时间:2016-12-24 21:49:30

标签: javascript arrays node.js

我正在玩Node并遇到一个奇怪的问题(对我来说很奇怪)。自从我做了任何Javascript以来已经很长时间了,所以这个问题很可能让我盯着我。

我遍历目录中的JSON文本文件列表,解析每个文件中的文本。它正确地在目录中移动;当我使用console.log查看时,每个对象都显示正确。

但是,当我尝试将其推送到数组时,没有任何反应,大小在循环结束时仍然是一个。这感觉就像一个范围问题。

感谢您的任何建议。

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

3 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:0)

您需要了解异步执行,并将此块放入:

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

fs.readdir

的最后一个括号之前

答案 2 :(得分: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?

如果您将console.logres.send移到fs.readdir的范围内,这可以解决您的问题:

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是阻塞方法。这意味着每次迭代都将在下一行执行之前完成。因此,在<{em> console.log之后移动res.send.forEach会产生预期效果。

有关.forEach的更多信息,请访问JavaScript, Node.js: is Array.forEach asynchronous?