范围内的变化承诺“然后”方法

时间:2014-06-29 10:42:02

标签: 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 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不在范围内。如何解决这个问题?

2 个答案:

答案 0 :(得分:5)

CoffeeScript包含保留词汇上下文的“胖箭头”。 (就像ES6中的JavaScript一样)。

每当您想保留this值时,请使用=>代替->

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

(请注意,在高度并发和密集的工作中,这可能很慢 - 您可能希望使用支持上下文的promise库,如Bluebird)

答案 1 :(得分:1)

我不知道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的实例。