从遍历文件夹function返回最终值

问题:为什么varvariables不会从walk()函数的外部返回值? 我该如何解决?

Hypothosis:这是asynchronous的,console.log发生得太早了。 这将导致我如何使这是一个Promise (我使用节点4.1.1)

 var walk = function(dir, done) { var results = []; fs.readdir(dir, function(err, list) { if (err) return done(err); var i = 0; (function next() { var file = list[i++]; if (!file) return done(null, results); file = dir + '/' + file; fs.stat(file, function(err, stat) { if (stat && stat.isDirectory()) { walk(file, function(err, res) { results = results.concat(res); next(); }); } else { results.push(file); next(); } }); })(); }); }; function traverseDirectories() { var things = walk('src/', function(err, results){ if(err) throw err; console.log(results) // ['dir/thing.png', 'dir/thing2.png'] return results; }); console.log(things) // undefined }; traverseDirectories(); 

问:为什么varvariables不会从walk()函数的外部返回值?

R.因为walk不返回任何东西(看一看,你会看到这是一个void函数)。


即使你把它作为一个承诺,你也不能像这样使用它:

 var things = walk(...); console.log(things); 

因为承诺是可以接受的,而且仍然是asynchronous的,所以它会是:

 walk(...).then(function(things) { // do something with things here }); 

要做你想做的事情,你需要一些在当前Javascript中不存在的东西。

有一个ES7提出的本地async/await将是一个callback天堂 ,但atm,你可以使用:

  • asynchronous/等待图书馆 (这是一个了不起的图书馆,但离本地很远,performance并不酷)
  • ES7编译器 – 你今天可以编写ES7编码,然后将编译成ES5(例如Babel )

但是,如果你已经在使用最新版本的NodeJS(4.0.0的时候) – 如果你不是,你真的应该 – 实现你想要的最好的方式是使用生成器

结合名为co的小型库,它将帮助您实现ES7 async/await提出的几乎所有内容,而且它将主要使用本机代码,因此可读性和性能都非常好:

 var co = require('co'); var traverseDirectories = co(function *traverseDirectories() { var things = yield walk('src/'); console.log(things) // there we go! }); function walk(dir, results) { return new Promise(function(resolve, reject) { fs.readdir(dir, function(err, list) { if (err) reject(err); var i = 0; (function next() { var file = list[i++]; if (!file) resolve(results); file = dir + '/' + file; fs.stat(file, function(err, stat) { if (stat && stat.isDirectory()) { walk(file).then(function(res) { results = results.concat(res); next(); }); } else { results.push(file); next(); } }); })(); }); }); } 

你可以在这个令人敬畏的Thomas Hunter的博客文章中阅读关于这个主题的更多信息 。