如下有个遍历文件夹的函数,如何才能得知它已经遍历结束了? 谢谢!
function walk(path, floor, handleFile) {
// handleFile(path, floor);
floor++;
fs.readdir(path, function(err, files) {
if (err) {
console.log('read dir error');
} else {
files.forEach(function(item) {
var tmpPath =path + '/' + item;
fs.stat(tmpPath, function(err1, stats,people,factor) {
if (err1) {
console.log('stat error');
} else {
if (stats.isDirectory()) {
walk(tmpPath, floor, handleFile);
} else {
handleFile(tmpPath,item, floor);
}
}
})
});
}
});
}
水平不够,wind的文档真难看懂。。。突袭到了半夜模仿着写了,心里没底,请指点下,谢谢: 1 这么样用异步函数+异步流程控制库,和直接用同步函数+个nexttick有什么区别? 2 有forEach、递归的方法,如何既利用异步的高效性,又能得到全部执行完毕的点?
var fs = require(‘fs’); var Wind = require(‘Wind’); var Binding = Wind.Async.Binding;
var myPath = 'e:/nodejs/home/public’; fs.readdirAsync = Binding.fromStandard(fs.readdir); fs.statAsync = Binding.fromStandard(fs.stat);
var walk = eval(Wind.compile("async",function (path, floor, handleFile) { floor++;
var myReadDirResult = $await(fs.readdirAsync(path));
//不知道为什么,forEach不行
for(var i = 0 ; i < myReadDirResult.length ; i++ ){
var item = myReadDirResult[i];
var tmpPath = path + '/' + item;
console.log('tmpPath:' + tmpPath);
var myStatResult = $await(fs.statAsync(tmpPath));
if (myStatResult.isDirectory()){
$await(walk(tmpPath, floor, handleFile).start());
}
else{
handleFile(tmpPath);
}
}
console.log(path + '文件夹结束');
}));
var main = eval(Wind.compile("async",function () { $await(walk(myPath, 0, function(filePath){ }).start()); console.log(‘结束’); }));
main().start();
console.log(‘这是最后一行’);
@ciiii 顺手用fibjs改写一下
var fs = require("fs");
(function walk(path, floor, handleFile) {
floor++;
var files = fs.readdir(path);
files.forEach(function(item) {
if (item.name !== '.' && item.name !== '..') {
var tmpPath = path + "/" + item.name;
if (fs.stat(tmpPath).isDirectory())
walk(tmpPath, floor, handleFile);
else
handleFile.call(null, tmpPath, item, floor);
}
});
})(".", 0, function(tmpPath, item, floor) {
console.log(tmpPath, item.name, floor);
});
@ngot 以上面你的代码为例,可以这样理解不: var files = fs.readdir(path);中的files其实仍然是异步的(不管他怎么实现的),是在将来某个不确定的时间点才能返回结果的。连带着下一句:files.forEach(…, 也是将来某个不确定的时候才会真正执行。 但如果是个和files无关的语句,是会继续执行,是有可能在readdir之前执行的。 也就是说和node一样,代码字面的顺序并非执行的顺序。既然如此,哪来的“js层面同步”呢?
function walk (path, handleFile, callback) {
var len = 1, // 文件|目录数,起始一个
floor = 0; // 第x个目录?
function done () {
// 完成任务, 运行回调函数
if (--len === 0) {
callback();
}
}
function composeErr (err) {
// 错误处理
console.log('stat error');
done(); // 以错误内容完成
}
function composeDir (path) {
// 目录处理
floor++;
fs.readdir(path, function (err, files) {
if (err) {
console.log('read dir error');
done(); // 目录完成
return;
}
len += files.length; // 子文件|子目录计数
files.forEach(function (filename) {
compose(path + '/' + filename); // 子内容新的操作
});
done(); // 目录完成
});
}
function composeFile (path) {
// 文件处理
handleFile(path, floor);
done(); // 文件完成
}
function compose (path) {
fs.stat(path, function (err, stats) {
if (err) {
composeErr(err);
return;
}
if (stats.isDirectory()) {
composeDir(path);
return;
}
composeFile(path);
});
}
compose(path);
}
@ciiii 不是,你看到的代码顺序,就是实际的执行顺序,不会跳着运行的。这个是我老大写的。具体可以看这个 http://cnodejs.org/topic/53df57aa111cfedf0b4500b5#53e250c3a3df2b8f3124cd16