如何判断递归嵌套的回调函数已经结束?(结束的节点有多个,promise好像只能判断单链情况)
发布于 9 年前 作者 xiaofuzi 10527 次浏览 最后一次编辑是 8 年前 来自 问答

如何判断一个递归嵌套的回调函数已经结束

var readDirRecur=  function(file, callback) {
        fs.readdir(file, function(err, files) {
        	if(err) throw err;
            files.forEach(function(item) {
            	var fullPath = file + '/' + item;
                fs.stat(fullPath, function(err, stats) {
                    if (err) throw err;
                    if (stats.isDirectory()) {
                        readDirRecur(fullPath, callback);
                    }else{
                    	/*not use ignore files*/
                    	if(item[0] == '.'){
                    		//console.log(item + ' is a hide file.');
                    	}else{
                    		fs.readFile(fullPath, 'utf8', function(err, data){
                                callback(item, data, fullPath);
                            })
                    	}
                    }
                })
            },
            function(err){
            	if(err) throw err;
            })
        })
    }
	```
	
	
	
	## 例如:递归读取一个目录下的所有文件,如何判断以读取完所有的文件?
4 回复

卧槽。。。。。。

不是已经读取完才会回调么

仅供参考

var fs = require('fs');
var readdir = promisify(fs.readdir);
var stat = promisify(fs.stat);
var readFile = promisify(fs.readFile);

// 简单实现一个promisify
function promisify(fn) {
  return function() {
    var args = arguments;
    return new Promise(function(resolve, reject) {
      [].push.call(args, function(err, result) {
        if(err) {
          reject(err);
        }else {
          resolve(result);
        }
      });
      fn.apply(null, args);
    });
  }
}
function readDirRecur(file, callback) {
    return readdir(file).then(function(files) {
      files = files.map(function(item) {
        var fullPath = file + '/' + item; 
        return stat(fullPath).then(function(stats) {
            if (stats.isDirectory()) {
                return readDirRecur(fullPath, callback);
            }else{
              /*not use ignore files*/
              if(item[0] == '.'){
                //console.log(item + ' is a hide file.');
              }else{
                return readFile(fullPath, 'utf8').then(function(data){
                  callback(item, data, fullPath);
                });
              }
            }
          })
      });
      return Promise.all(files);
    });
}

readDirRecur('/someDir', function(item, data, fullPath) {
 // ...
 console.log(fullPath);
}).then(function() {
  console.log('done');
}).catch(function(err) {
  console.log(err);
});

正好写过遍历目录获得目录下所有文件的属性 使用变量endTag记录进度

var getDirInfo = function(dir, cb) {
    var ret = [];
    fs.readdir(dir, function(err, files, index) {
        // ...
        var endTag = 0;
        files.forEach(function(file, index) {
            var filePath = dir + '/' + file;
            fs.stat(filePath, function(err, data) {
                // ...
                ret.push(data);
                if (++endTag == files.length) {
                    return cb(ret);
                }
            });
        });
    });
}

getDirInfo('e:/', function(data) {
    console.log(data);
});

非常感谢@William17的回答,关键时刻给出了思路。顺便刺激了我去深入了解promise

回到顶部