我是Node.js的新手。当我学习Node.js时,我突然想到了一个与异步/同步相关的问题。我从其他例子中了解了异步函数和回调的逻辑。然而,我不明白下面的例子。我引用的是:http://code-maven.com/list-content-of-directory-with-nodejs
为什么下面的代码不能正常工作?作者说,这是由fs.stat()方法的第一个参数引起的。在最后两个工作示例中显示了正确的方法。我不理解工作示例和非工作示例之间的区别,以及为什么第一个示例不能正常工作,最后两个示例工作正常。
var fs = require('fs');
if (process.argv.length <= 2) {
console.log("Usage: " + __filename + " path/to/directory");
process.exit(-1);
}
var path = process.argv[2];
fs.readdir(path, function(err, items) {
for (var i=0; i<items.length; i++) {
var file = path + '/' + items[i];
console.log("Start: " + file);
fs.stat(file, function(err, stats) {
console.log(file);
console.log(stats["size"]);
});
}
});产出如下:
$ node examples/node/list_dir_direct.js ~/work/code-maven.com/examples/
Start: /home/gabor/work/code-maven.com/examples//blocking-read-file.js
Start: /home/gabor/work/code-maven.com/examples//node_hello_world.js
Start: /home/gabor/work/code-maven.com/examples//node_hello_world_port.js
Start: /home/gabor/work/code-maven.com/examples//non-blocking-read-file.js
Start: /home/gabor/work/code-maven.com/examples//process_exit.js
Start: /home/gabor/work/code-maven.com/examples//raw_command_line_arguments.js
Start: /home/gabor/work/code-maven.com/examples//read_dir.js
Start: /home/gabor/work/code-maven.com/examples//stats.js
/home/gabor/work/code-maven.com/examples//stats.js
97
/home/gabor/work/code-maven.com/examples//stats.js
243
/home/gabor/work/code-maven.com/examples//stats.js
270
/home/gabor/work/code-maven.com/examples//stats.js
151
/home/gabor/work/code-maven.com/examples//stats.js
18
/home/gabor/work/code-maven.com/examples//stats.js
324
/home/gabor/work/code-maven.com/examples//stats.js
27
/home/gabor/work/code-maven.com/examples//stats.js
1382调试输出打印出了预期的名称,但是在fs.stat()的回调中,我们继续打印相同的文件名。的输出结果比较
$ ls -l ~/work/code-maven.com/examples/
total 64
-rw-r--r-- 1 gabor staff 97 Jan 29 14:26 blocking-read-file.js
-rw-r--r-- 1 gabor staff 243 Jan 27 12:34 node_hello_world.js
-rw-r--r-- 1 gabor staff 270 Jan 27 12:34 node_hello_world_port.js
-rw-r--r-- 1 gabor staff 151 Jan 29 14:26 non-blocking-read-file.js
-rw-r--r-- 1 gabor staff 18 Jan 31 08:24 process_exit.js
-rw-r--r-- 1 gabor staff 27 Jan 29 14:54 raw_command_line_arguments.js
-rw-r--r-- 1 gabor staff 324 Jan 31 15:26 read_dir.js
-rw-r--r-- 1 gabor staff 1382 Jan 31 10:45 stats.js文件名的大小似乎与文件名相匹配,因为这些文件的打印顺序与我们调用fs.stat()的顺序相同,但出于某种原因,文件变量的内容对于每个回调都是相同的。这是因为文件变量只是一个简单的全局变量(从回调的角度来看),并且在执行第一个回调时,文件变量已经被分配到目录中的最后一个条目。
下面的代码工作正常。
var fs = require('fs');
if (process.argv.length <= 2) {
console.log("Usage: " + __filename + " path/to/directory");
process.exit(-1);
}
var path = process.argv[2];
fs.readdir(path, function(err, items) {
for (var i=0; i<items.length; i++) {
var file = path + '/' + items[i];
console.log("Start: " + file);
fs.stat(file, generate_callback(file));
}
});
function generate_callback(file) {
return function(err, stats) {
console.log(file);
console.log(stats["size"]);
}
};另外,下面的代码也能正常工作。
var fs = require('fs');
if (process.argv.length <= 2) {
console.log("Usage: " + __filename + " path/to/directory");
process.exit(-1);
}
var path = process.argv[2];
fs.readdir(path, function(err, items) {
for (var i=0; i<items.length; i++) {
var file = path + '/' + items[i];
console.log("Start: " + file);
fs.stat(file, function(f) {
return function(err, stats) {
console.log(f);
console.log(stats["size"]);
}
}(file));
}
});发布于 2016-06-26 12:48:22
在第一个例子中,通过引用传递工作。文件变量是通过引用传递的,因此回调函数接受文件变量的最后一个值,并且工作不正确。在第二个和第三个例子中,按值传递的作品。文件变量通过值传递,因此回调函数正确地接受每个文件的名称。
https://stackoverflow.com/questions/38037767
复制相似问题