范围内的变化承诺“那么”方法

我写了下面的程序,每N毫秒处理一个目录中的所有文件:

fs = require "fs" Q = require "q" class FileProcessor constructor: (options) -> @dir = options.dir @delay = options.delay processFiles: -> Q.nfcall fs.readdir, @dir .then (files) -> Q.all files.map (file) -> @processFile file # <-- Error! .then -> Q.delay @delay .then -> @processFiles() .done() processFile: (file) -> deferred = Q.defer() # Does some stuff. return deferred.promise fp = new FileProcessor(dir: "photos", delay: 1000) fp.processFiles() 

在第11行我得到这个错误:

 TypeError: undefined is not a function 

看来@processFile不在范围之内。 如何解决这个问题?

CoffeeScript包含保留词汇语境的“胖箭头”。 (就像ES6中的JavaScript)。

每当你想保存this值,使用=>而不是->

 @x = 5 someFnCall someArg .then (result) => console.log @x # this will work 

(请注意,在高度并发和密集的工作中,这可能会很慢 – 您可能希望使用支持上下文的承诺库,而不是Bluebird)

我不知道咖啡因,所以我会回答在正常的JS:

您的processFiles函数转换为:

 FileProcessor.prototype.processFiles = function() { return Q.nfcall(fs.readdir, this.dir).then(function(files) { return Q.all(files.map(this.processFile)); }).then(function() { return Q.delay(this.delay); }).then(this.processFiles).done(); }; 

你可以清楚地看到this.processFile被调用传递给then的一个匿名函数。 这意味着this范围不是你的FileProcessor的一个实例。