CNode

for 循环引用出错的问题在 Node 也存在?

Jjiyinyiyong发布于13 年前最后回复13 年前4 回复4296 浏览0 收藏

想写一个递归创建目录的脚本, 开始发现创建目录都不对的.. 先是一个模块:

events = require "events"
exports.ring = ring = new events.EventEmitter

create_file = (base_path, data) ->
  if (typeof data) is "string"
    file_path = path.join base_path, data
    fs.writeFile file_path, ""
  else
    for key, value of data
      new_path = path.join base_path, key
      fs.mkdir new_path, ->
        create_file new_path, value

ring.on "create", (tree, base_path) ->
  base_path = base_path or "."
  create_file base_path, tree

然后在另一个文件引用:

file_tree =
  "parent": "child"
  "tree":
    "a": "aa"
    "b": "bbb"

scaffold = require("../lib/index").ring

scaffold.emit "create", file_tree

创建的目录结构是这样的:

➤➤ tree
.
|-- create.coffee
|-- parent
`-- tree
    |-- a
    `-- b
        `-- bbb

create.coffee 是我跑脚本的文件, 文件树几个子文件没有创建成功.. 然后我把 for in 循环改成了 Object.keysforEach, 文件创建成功, 以前在 DOM 节点绑定操作的时候遇到过这个问题, 为什么文件操作里也有? 记得原来的说法是循环当中没有创建作用域, 可传值在 JS 里也出错的么?

查看回复

回复 (4)

S
shiedman#2·13 年前
  new_path = path.join base_path, key
  fs.mkdir new_path, ->
    create_file new_path, value

为了让所有人看明白,转换成正常的javascript语法

new_path=path.join(base_path,key);
fs.mkdir(new_path,function(err){
    create_file(new_path,value);
});

第二行的new_path确实是传值给fs.mkdir函数,但是第三行的new_path却不是在fs,mkdir的作用域内,而是在闭包回调函数的作用域内,它是指向第一行的new_path的。

模拟测试代码

var tree={a:'a',b:'b'};
var keys=Object.keys(tree);
for(var i=0;i<keys.length;i++){
    var path='/root/'+keys[i];
    create_path(path,function(err){
        console.log('from callback - %s',path);
    });
}
function create_path(path,callback){
    process.nextTick(function(){
        console.log('from function - %s',path);
        callback();
    });
}
J
jiyinyiyong#3·13 年前
引用 shiedmannew path = path.join base path, key fs.mkdir new path, create file new path, value 为了让所有人看明白,转换成...

这么说完全是异步的操作都会出这样的问题咯.. 而且 DOM 和 fs 的操作全都是异步的, 这样的确好理解多了 那么以后对于这样的情况都应该用闭包处理一遍了 .. 怎么会这样的.. 不能传值

S
shiedman#4·13 年前

非不能,只是闭包函数没有明确定义接受值的参数,不怕麻烦可以bind一个参数进去,例如这样就能达到传值的目的。

var tree={a:'a',b:'b'};
var keys=Object.keys(tree);
for(var i=0;i<keys.length;i++){
    var path='/root/'+keys[i];
    create_path(path,function(path,err){
        console.log('from callback - %s',path);
    }.bind(undefined,path));
}
function create_path(path,callback){
    process.nextTick(function(){
        console.log('from function - %s',path);
        callback();
    });
}
参与回复
登录后即可参与回复。登录