dsi*_*ard 1 closures callback node.js
我用javascript工作了很多但是昨天我开始使用node.js. 这是一个在文件夹文件上运行jslint的小脚本.对于此示例,我将命令更改为调用ls而不是jslint.
var sys = require("sys");
var fs = require("fs");
var cp = require('child_process');
var path = fs.realpathSync("./src/");
fs.readdir(fs.realpathSync("./src/"), function(err, files) {
for (var i = 0; i < files.length; i++) {
var filename = files[i];
var complete = path + filename;
// Run jslint on each file
var jslint = cp.exec("ls " + complete, function(error, stdout, stderr) {
console.log(filename + " : " + stdout);
});
}
});
Run Code Online (Sandbox Code Playgroud)
输出是这样的:
jskata.nofreeze.js:/home/dan/php/jskata/src/jskata.undo.js
jskata.nofreeze.js:/home/dan/php/jskata/src/jskata.nofreeze.js
jskata.nofreeze.js:/home/dan/php/jskata/src/jskata.timezone.js
为什么当文件名明显与?的结果相匹配时,console.log(filename + " : " + stdout);总是会打印该行?node.js中的闭包和作用域是否与javascript不同?jskata.nofreeze.jsls
Ivo*_*zel 13
不,它们没有任何不同,这只是JavaScript中闭包最常见的陷阱.
看,你处于一个循环中,你在循环的filename每次迭代中分配局部变量,因此你实际上覆盖了它的值.由于它始终是相同的局部变量,并且每个引用filename都有闭包,因此回调内部的值会在循环的每次迭代中获得更新.
'jskata.nofreeze.js'恰好是目录中的最后一个文件,因此它也是分配给的最后一个值filename.
要解决它,您需要传递filename 每个值的值:
// Run jslint on each file
(function(c, f) {
cp.exec("cat " + c, function(error, stdout, stderr) {
console.log(f + " : " + stdout);
});
})(complete, filename);
Run Code Online (Sandbox Code Playgroud)
这使整个过程变得有效,即使它有点难看.如果你不想用更多的匿名函数来混淆你的内部循环,你当然可以把它移到一个命名函数中.
| 归档时间: |
|
| 查看次数: |
1845 次 |
| 最近记录: |