如何在asynchronous操作中指示“完成”

给定这个代码在指定的目录和子目录中的文件,我怎么去指示操作完成?

function walkDirs(dirPath) { var fs = require('fs'), path = require('path'), events = require('events'), count = 0, emitter = new events.EventEmitter(); function walkDir(dirPath) { function readDirCallback(err, entries) { for (var idx in entries) { var fullPath = path.join(dirPath, entries[idx]); (function statHandler(fullPath) { fs.stat(fullPath, function statEach(err, stats) { if (stats) { if (stats.isDirectory()) { walkDir(fullPath); } else if (stats.isFile()) { count += 1; emitter.emit('counted', count, fullPath); } } }); })(fullPath); } } fs.readdir(dirPath, readDirCallback); } walkDir(dirPath); return emitter; } var walker = walkDirs('C:'); 

我已经试过了,

  • 在一个我认为合适的地方fs.readdir(dirPath, readDirCallback)一个事件来指示“完成”,特别是在fs.readdir(dirPath, readDirCallback)调用之后。
  • 修改statHandler()返回添加的计数。 (我意识到这与在该函数内增加count没有什么不同。

这两个都失败了,因为当选中时, count的值是0.我确定我并没有等待操作(计数文件)完成。 很明显,我需要发起一个callback或事件来完成正确的计数。

我知道代码是成功计数,因为当附加一个debugging器,计数值是预期的。

在这一点上,我相当确定,我不知道如何进一步进行。 特别 –

我如何在asynchronous操作中实现“完成”?

asynchronousJavaScript函数通常在完成时调用callback函数。 在这种情况下,如果您有其他事件,则done事件将是适当的。 Promise现在通常比callback更受欢迎,但是您首先需要了解callback。

由于readdir是asynchronous的,下一行的执行并不意味着完成。 与同步代码相比,这就是asynchronous代码的混淆。 如果我是你,我会使用debugging器,并通过一些非常简单(比这更简单)的asynchronous示例。 习惯并且棘手需要一些时间。

有关步行目录,请参阅https://www.npmjs.com/package/walk 。 你不想在这里重新发明轮子。 一定要确保Google和/或在npmjs上search现有的模块。

一旦你确定你真的了解callback和asynchronous代码,那么你可以移动到async模块,然后,承诺与bluebird ,ES6诺言,等等这样的行这样的https://www.npmjs.com/ package / co可能是有用的。

你可以通过使用promise来实现这一点。 在这个例子中,我select了Q.

 npm install q 

只要通过调用.resolve()函数来考虑asynchronous函数,就可以解决您的承诺。 当你的承诺得到解决,它会调用你的成功callback,然后在你的承诺对象的walkDirs .then()函数,这是walkDirs.then()函数在您的promise被parsing或拒绝时触发。 如果您拒绝您的承诺,错误callback将被调用。

 var q = require('q'); function walkDirs(dirPath) { var deffered = q.defer(); var fs = require('fs'), path = require('path'), events = require('events'), count = 0, emitter = new events.EventEmitter(); function walkDir(dirPath) { function readDirCallback(err, entries) { for (var idx in entries) { var fullPath = path.join(dirPath, entries[idx]); (function statHandler(fullPath) { fs.stat(fullPath, function statEach(err, stats) { if (stats) { if (stats.isDirectory()) { walkDir(fullPath); } else if (stats.isFile()) { count += 1; emitter.emit('counted', count, fullPath); deffered.resolve(emitter); // resolve promise } } }); })(fullPath); } } fs.readdir(dirPath, readDirCallback); } walkDir(dirPath); return q.promise; } walkDirs('C:') .then(success, error) //can also take error callback if promise is rejected. function success(function(data) { //data = resolved data. console.log("is successfully done"); }) function errer(function() { console.log("is errorly done"); })