【问题标题】:Scope changes inside promise "then" methods承诺“then”方法内的范围更改
【发布时间】:2014-08-19 22:47:59
【问题描述】:

我编写了以下程序,每 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 不在范围内。如何解决这个问题?

【问题讨论】:

    标签: javascript node.js coffeescript promise q


    【解决方案1】:

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

    当您想保留this 值时,请使用=&gt; 而不是-&gt;

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

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

    【讨论】:

      【解决方案2】:

      我不知道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 在非严格模式下设置为全局上下文,否则根据 Promises/A+ 规范设置为未定义。
      • 同样,第二个.then 中的Q.delay(this.delay) 会出错,最后一个this.processFiles 会起作用,尽管没有设置this 值。
      猜你喜欢
      • 2017-04-23
      • 2020-04-27
      • 2019-02-10
      • 2014-11-06
      • 1970-01-01
      • 2020-06-03
      • 1970-01-01
      • 2021-10-17
      • 2015-01-23
      相关资源
      最近更新 更多