匿名函数用作回调,但定义的函数不

Anonymous function works as callback but defined function does not

我有一个看起来像这样的模块:

module.exports = AtomMarkdownLabels =
  # other stuff here

  file_changed_added: (file_path) =>
    fs.readFile file_path, 'utf-8', @process_yaml
    console.log 'file changed'

  process_yaml: (err, data) =>
    console.log "process_yaml is called"

我知道 file_changed_added 是从其他函数调用的,我在控制台中看到 "file changed" 输出,但是 process_yaml 如果我更改 [=12] 则不会=]到

file_changed_added: (file_path) =>
    fs.readFile file_path, 'utf-8', (err, data) =>
      console.log "test"
    console.log 'file changed'

我看到 "test" 和 "file changed" 都被正确调用了。可能发生了什么?

=> 有两个稍微不同的目的:

  1. 当定义命名函数(f = => ...)或匿名函数f(x, => ...))时,=>只是确保函数内部的@是与周围上下文中的 @ 相同。

  2. 在class中定义方法时:

    class C
      m: => ...
    

    => 确保 m 内的 @ 将是 C.

  3. 的实例

这两种用途都在创建绑定函数,但它们绑定到不同的事物。

您正在使用这种结构:

obj =
  func: =>
    # ...

这相当于:

f = =>
  # ...
obj =
  func: f

因为您使用的是普通旧对象而不是 class。那么 @ 在您的 AtomMarkdownLabels 定义之外是什么? @ 不会有任何用处,特别是,它不会是您的 AtomMarkdownLabels 对象,也不会有 process_yaml 属性 所以 @process_yaml file_changed_added 内将是 undefined 或错误。

我不确定 Atom 具体要你做什么 return 但 class 应该可以,像这样:

# Use a class so that => does what you're expecting it to do
class AtomMarkdownLabels
  # other stuff here

  file_changed_added: (file_path) =>
    fs.readFile file_path, 'utf-8', @process_yaml
    console.log 'file changed'

  # you may or may not need => here
  process_yaml: (err, data) =>
    console.log "process_yaml is called"

# Export an instance of your class
module.exports = new AtomMarkdownLabels

如果你想或必须使用普通对象,那么你可以完全绕过 @ 并像这样做:

# Just plain old functions so define them that way
process_yaml = (err, data) ->
  console.log "process_yaml is called"

file_changed_added = (file_path) ->
  fs.readFile file_path, 'utf-8', process_yaml
  console.log 'file changed'

module.exports = AtomMarkdownLabels =
  # other stuff here

  file_changed_added: file_changed_added

或者像这样:

# Explicitly name your object rather than using @
module.exports = AtomMarkdownLabels =
  # other stuff here

  file_changed_added: (file_path) ->
    fs.readFile file_path, 'utf-8', AtomMarkdownLabels.process_yaml
    console.log 'file changed'

  process_yaml: (err, data) ->
    console.log "process_yaml is called"

这也应该解决几天前的 CoffeeScript 问题。