如何避免条件表达式中coffeescript中的隐式“返回”?

时间:2013-03-18 04:04:48

标签: javascript node.js coffeescript deferred promise

我正在实现一个具有延迟值的函数来返回,并且在函数中我有许多嵌套的条件表达式:

e.g:

deferred = Q.defer()
FS.readFile("foo.txt", "utf-8", (error, text) ->
    if error
      deferred.reject(new Error(error))
    else
      deferred.resolve(text)
)
return deferred.promise

将编译成:

var deferred;

deferred = Q.defer();

FS.readFile("foo.txt", "utf-8", function(error, text) {
  if (error) {
    --> return <-- deferred.reject(new Error(error));
  } else {
    --> return <-- deferred.resolve(text);
  }
});

return deferred.promise;

我只需要最后一次返回,但不是if / else返回(即编译代码中的 - &gt; return&lt; -

如何避免coffeescript编译器出现这种行为(不需要隐式返回)?

3 个答案:

答案 0 :(得分:12)

Coffeescript会自动返回最后一个表达式的结果,因此如果您不希望它返回if的结果,那么您需要添加另一个表达式。在这种情况下,只需添加return

FS.readFile "foo.txt", "utf-8", (error, text) ->
  if error
    deferred.reject new Error(error)
  else
    deferred.resolve text
  return

此外,error已经是Error个对象,因此您可以直接拒绝它。

deferred.reject(error)

答案 1 :(得分:2)

你不能,确切地说。您可以在不需要时忽略它们(这是最常见的事情),或者通过在函数末尾添加附加语句来提供明确的替代方法。我认为在你的代码库中一直试图这样做就是打击你无法赢得的语言的战争,所以我个人的建议就是接受Ashkenas先生隐含的回归并继续你的快乐方式。

fs.readFile "foo.txt", "utf-8", (error, text) ->

  # postfix style if statement here avoids the else
  # of course, the value returned you may not like, so 
  # you probably won't use this style, but my boilerplate for
  # error handling is
  # return callback(error) if error

  return deferred.reject(new Error(error)) if error
  deferred.resolve(text)

  # Here you can add an explicit return like
  return

  # or some other expression
  null

  # or 'this' in cases where chainability might be nice
  this

  # or so you don't accidentally delete this statement later thinking it is
  # useless
  return null

这些表格中的任何一种都可以使用,但在实践中我并不常见这些

答案 2 :(得分:0)

我总是这样做:

f = ->
  deferred = Q.defer()
  FS.readFile ..., ( error, text ) ->
    return deferred.reject error if error?
    deferred.resolve text
  return deferred.promise

第一个return用于停止执行,而不是返回值。

你仍然会在回调的最后一行中从JS中获得额外的(并且无意义的)return;为避免这种情况,请插入额外的return null(如果您愿意,只需插入return)。

我不确定我喜欢CoffeeScript的隐式return插入;可能会声称明确比隐含更好。另外,可以说第一个return不应该是return而是另一个关键字,例如stopfinish或其他关键字。

作为一个不相关的旁注,我在使用承诺时没有观察到任何明显的优势。相反,我发现它们在我的代码中非常具有侵入性,那些deferred以及其他概念放在异步编程之上。