Nodejs Express fs 将文件迭代到数组或对象失败
因此,我尝试使用 Nodejs Express FS 模块来迭代我的应用程序中的目录,将每个文件名存储在一个数组中,我可以将其传递到我的 Express 视图并迭代列表,但我很难做到这一点。当我在 files.forEach 函数循环中执行 console.log 时,它打印文件名很好,但是一旦我尝试执行以下操作,例如:
var myfiles = [];
var fs = require('fs');
fs.readdir('./myfiles/', function (err, files) { if (err) throw err;
files.forEach( function (file) {
myfiles.push(file);
});
});
console.log(myfiles);
它失败了,就只记录一个空对象。所以我不确定到底发生了什么,我认为这与回调函数有关,但是如果有人可以引导我了解我做错了什么,以及为什么它不起作用(以及如何使其工作),那就是非常感谢。
So Im trying to use the nodejs express FS module to iterate a directory in my app, store each filename in an array, which I can pass to my express view and iterate through the list, but Im struggling to do so. When I do a console.log within the files.forEach function loop, its printing the filename just fine, but as soon as I try to do anything such as:
var myfiles = [];
var fs = require('fs');
fs.readdir('./myfiles/', function (err, files) { if (err) throw err;
files.forEach( function (file) {
myfiles.push(file);
});
});
console.log(myfiles);
it fails, just logs an empty object. So Im not sure exactly what is going on, I think it has to do with callback functions, but if someone could walk me through what Im doing wrong, and why its not working, (and how to make it work), it would be much appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
myfiles 数组为空,因为在调用 console.log() 之前尚未调用回调。
您需要执行以下操作:
请记住,节点中的所有内容都会同时发生,从某种意义上说,除非您在回调中进行处理,否则无法保证异步函数已完成。
解决这个问题的一种方法是使用 EventEmitter:
The myfiles array is empty because the callback hasn't been called before you call console.log().
You'll need to do something like:
Remember, everything in node happens at the same time, in the sense that, unless you're doing your processing inside your callbacks, you cannot guarantee asynchronous functions have completed yet.
One way around this problem for you would be to use an EventEmitter:
正如一些人提到的,您使用的是异步方法,因此您有一个不确定的执行路径。
然而,有一个简单的方法可以解决这个问题。只需使用该方法的同步版本:
这应该可以按照您的意愿工作。但是,使用同步语句并不好,因此除非同步非常重要,否则不应该这样做。
在这里阅读更多内容:fs.readdirSync
As several have mentioned, you are using an async method, so you have a nondeterministic execution path.
However, there is an easy way around this. Simply use the Sync version of the method:
That should work as you want. However, using sync statements is not good, so you should not do it unless it is vitally important for it to be sync.
Read more here: fs.readdirSync
fs.readdir
是异步的(与 Node.js 中的许多操作一样)。这意味着console.log
行将在readdir
有机会调用传递给它的函数之前运行。您需要:
将
console.log
行放入给readdir
的回调函数中,即:或者简单地对
forEach< 中的每个文件执行一些操作/代码>。
fs.readdir
is asynchronous (as with many operations in node.js). This means that theconsole.log
line is going to run beforereaddir
has a chance to call the function passed to it.You need to either:
Put the
console.log
line within the callback function given toreaddir
, i.e:Or simply perform some action with each file inside the
forEach
.确实如此。
fs.readdir
向文件系统发出异步请求以获取该信息,并在稍后的某个时间使用结果调用回调。因此,
function (err, files) { ... }
不会立即运行,但console.log(myfiles)
会立即运行。在稍后的某个时间点,
myfiles
将包含所需的信息。顺便说一句,您应该注意
files
已经是一个数组,因此手动将每个元素附加到其他空白数组实际上没有意义。如果想法是将多个调用的结果放在一起,则使用.concat
;如果你只想获取一次数据,那么你可以直接分配myfiles = files
。总的来说,您确实应该阅读“Continuation-passing style” 。
Exactly.
fs.readdir
makes an asynchronous request to the file system for that information, and calls the callback at some later time with the results.So
function (err, files) { ... }
doesn't run immediately, butconsole.log(myfiles)
does.At some later point in time,
myfiles
will contain the desired information.You should note BTW that
files
is already an Array, so there is really no point in manually appending each element to some other blank array. If the idea is to put together the results from several calls, then use.concat
; if you just want to get the data once, then you can just assignmyfiles = files
directly.Overall, you really ought to read up on "Continuation-passing style".
我遇到了同样的问题,根据这篇文章中给出的答案,我用承诺解决了这个问题,这在这种情况下似乎非常有用:
注意:你不必将找到的文件推送到新数组中,因为您已经从 fs.readdir()'c 回调中获取了一个数组。根据节点文档:
我相信这是非常优雅和方便的解决方案,最重要的是 - 它不需要您在脚本中引入和处理新模块。
I faced the same problem, and basing on answers given in this post I've solved it with Promises, that seem to be of perfect use in this situation:
Note: you don't have to push found files into new array because you already get an array from fs.readdir()'c callback. According to node docs:
I belive this is very elegant and handy solution, and most of all - it doesn't require you to bring in and handle new modules to your script.