【问题标题】:Javascript/Coffeescript Using Hash of Functions As Argument使用函数哈希作为参数的 Javascript/Coffeescript
【发布时间】:2015-03-01 18:40:01
【问题描述】:

我有一些看起来像这样的 Coffeescript(提前为复杂性道歉):

doc = new ChargerServerDoc(Chargers.find({id:site.id}), site)

doc.set_defaults().merge().needs_update
  update: (id, doc) ->
    Chargers.update id, $set: doc, (error, result) ->
      if error
        run_stats.error_count += 1
        "error"
      else
        run_stats.update_count += 1
        "update"

    return

  insert: (doc) ->
    Chargers.insert doc, (error, result) ->
      if error
        run_stats.error_count += 1
        "error"
      else
        run_stats.insert_count += 1
        "insert"

    return

它应该创建某种文档并作为回调实现对数据库的插入或更新。

needs_update: (callbacks = null) ->

  console.log inspect arguments

  if callbacks is null
    return true unless @is_equal(@working_document, @retrieved_document)
    return false
  else
    console.log """
    callbacks not null:
    insert: #{inspect callbacks['insert']}
    update: #{inspect callbacks['update']} 
    """
    data = @get()
    if @is_equal(@working_document, @retrieved_document)
      throw 'requires update callback' if _.isEmpty(callbacks.update)
      return callbacks.update.call(this, data._id, _.omit(data, '_id'))
    else
      throw 'require insert callback' if _.isEmpty(callbacks.insert)
      return callbacks.insert.call(this, _.omit(data, '_id'))

如您所见,needs_update 函数中充斥着console.log 语句。这是在 node.js 中运行的,它是在启动时运行一次的事情。所以在节点检查器中观察并不容易。至少我还没弄清楚怎么做。

无论如何,这其中有趣的部分是console.log inspect argumentsinspect 只是将对象转换为 JSON 字符串,以便我可以读取它。结果总是{"0":{}}

这就是我卡住的地方。我可以看到它正在传递一个哈希,但哈希中没有任何内容。更奇怪的是,当我用纯 Javascript 手写它时,也会发生同样的行为。

我试图减少它并重现它无济于事。此代码有效:

h =
  f1: (a) -> 'one'
  f2: (b) -> 'two'

test = (fn) ->
  console.log fn.f1.call()
  console.log fn.f2.call()

test(h)

有人知道为什么第一个代码失败而简化的示例有效吗?

谢谢!

【问题讨论】:

  • 是的。它调用 JSON.stringify() (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…)。
  • @muistooshort-- 以callbacks not null 开头的console.log 与您所说的非常相似:它检查了我期望的两个键/值对,它们都出现了undefined。我试图简化它,但从根本上说,我不明白为什么这些参数会出现一个空的哈希值。
  • 原来代码没问题。出了问题的是 throw 'requires update callback' if _.isEmpty(callbacks.update) 和相同的 insert 即使提供了回调,也会触发。出于某种原因,提供的函数被 Underscore 评估为空。删除引发异常的行解决了问题。所以我将重新构建这个问题:为什么这些没有回调的测试会评估为 true?

标签: javascript node.js callback coffeescript underscore.js


【解决方案1】:

你没有正确使用_.isEmpty。来自fine manual

isEmpty _.isEmpty(object)

如果可枚举的对象不包含任何值(没有可枚举的自身属性),则返回true。对于字符串和类数组对象_.isEmpty 检查长度属性是否为0。

函数不是可枚举的对象,也不是字符串或类似数组的对象。你给_.isEmpty 一些它不理解的东西,所以你正在调用未指定的行为。原来_.isEmpty 会返回true 任何它不理解的东西。

如果你想看看某个东西是否是一个函数,_.isFunction 可能会更好地为你服务:

throw 'requires update callback' unless _.isFunction(callbacks.update)

【讨论】:

  • 我正在检查是否提供了参数,而不是检查它是否是一个函数。你可能是对的,检查它是否是一个函数是有道理的,但我不确定isEmpty 是否真的被错误地使用了。看 Github 上的代码,cmets 和代码告诉我,如果你传 null,你就会得到 true。在这里:if (obj == null) return true;。 (github.com/jashkenas/underscore/blob/master/underscore.js#L1168) 因此,虽然注释没有明确引用 null 作为可能的“空”值,但代码确实如此。我相信这就是几乎所有空函数或空白函数的工作方式。
  • 接受为正确答案,因为测试确实应该是针对是否提供回调函数。
  • 是的,代码将null(和undefined,因此== null而不是=== null)视为“空”,但它仍然期望某些类型的非空输入。
猜你喜欢
  • 2011-07-16
  • 1970-01-01
  • 2013-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-05
  • 1970-01-01
相关资源
最近更新 更多