Javascript “承诺内的范围变更”;然后";方法
我编写了以下程序,每N毫秒处理一个目录中的所有文件:Javascript “承诺内的范围变更”;然后";方法,javascript,node.js,coffeescript,promise,q,Javascript,Node.js,Coffeescript,Promise,Q,我编写了以下程序,每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 file
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()
似乎@processFile
不在范围内。如何修复此问题?CoffeeScript包含保留词汇上下文的“胖箭头”。(就像ES6中的JavaScript一样)
无论何时要保留此
值,请使用=>
而不是->
:
@x = 5
someFnCall someArg
.then (result) => console.log @x # this will work
(注意,在高度并行和密集的工作中,这可能会很慢-您可能希望使用支持上下文的promise库,而不是像Bluebird一样)CoffeeScript包含保留词汇上下文的“胖箭头”。(就像ES6中的JavaScript一样)
无论何时要保留此
值,请使用=>
而不是->
:
@x = 5
someFnCall someArg
.then (result) => console.log @x # this will work
(请注意,在高度并行和密集的工作中,这可能会很慢-您可能希望使用支持上下文的promise库,如Bluebird)我不知道coffeescript,因此我将用普通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的一个匿名函数中被调用。这意味着这个
范围不是您的文件处理器的实例。我不知道coffeescript,所以我将用普通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的实例。Q.all
行中的this.processFile
将抛出一个错误,因为this
在非严格模式下设置为全局上下文,在其他情况下根据承诺/A+规范未定义。类似地,Q.delay(this.delay)
在第二个中。然后
将出错,最后一个此。processFiles
将工作,虽然未设置此
值。Q.all
行中的此.processFile
将抛出错误,因为此
在非严格模式下设置为全局上下文,并根据承诺/a+规范未定义其他值。同样,第二个中的Q.delay(this.delay)
。然后将出错,最后一个this.processFiles
将起作用,但没有this
值集。