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

时间:2021-08-17 22:30:58

I am implementing a function that has deferred value to return and within the function I have many nested conditional expressions:

我正在实现一个递延值返回的函数,在这个函数中我有许多嵌套的条件表达式:

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

which than will be compiled into:

将汇编成:

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;

I need only the last return, but not the if/else returns (i.e. --> return <-- in the compiled code)

我只需要最后一个返回值,而不需要if/else返回值(例如,编译代码中的>返回<)

How can I avoid such a behavior (implicit returns where they are do not needed) of the coffeescript compiler?

如何避免这样的行为(在不需要隐式返回的地方)?

3 个解决方案

#1


12  

Coffeescript automatically returns the result of the last expressions, so if you don't want it to return the results of the if then you need to add another expressions. In this case, just add return.

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

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

Also, error is already an Error object, so you can just reject it directly.

而且,错误已经是一个错误对象,所以您可以直接拒绝它。

deferred.reject(error)

#2


2  

You can't, exactly. You can either ignore them when not needed (which is the most common thing to do) or provide an explicit alternative by adding an additional statement at the end of the function. I think trying to do this all the time in your code base is fighting a war against the language you cannot win, so my personal recommendation is just accept Mr. Ashkenas's implicit return and go on your merry way.

你不能,没错。您可以在不需要时忽略它们(这是最常见的做法),也可以通过在函数末尾添加一个附加语句来提供显式的替代方法。我认为在你的代码库中一直这么做就是在与你赢不了的语言作战,所以我个人的建议是接受德什肯纳斯先生的含蓄回归,然后继续你的快乐之路。

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

any of those forms will work, but in practice I don't see these commonly

任何一种形式都可以,但在实践中,我不经常看到这些形式

#3


0  

i always do it like this:

我总是这样做:

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

the first return is there to stop execution, not to return a value.

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

you still get an additional (and meaningless) return in your JS from the last line of the callback; to avoid that one, insert an additional return null (or simply return if you prefer that).

您仍然可以从回调的最后一行获得额外的(而且毫无意义的)JS返回;为了避免这种情况,插入一个额外的返回null(如果您喜欢,可以直接返回)。

i'm not sure i like CoffeeScript's implicit return insertion; it might be claimed that 'explicit is better than implicit'. also, it could be argued that the first return shouldn't be a return but another keyword, like, say, stop or finish or somesuch.

我不太喜欢CoffeeScript的隐式返回插入;有人可能会说,“显性比隐性好”。同样,第一次返回不应该是返回,而应该是另一个关键字,比如stop or finish或somesuch。

as an unrelated sidenote, i haven't observed any noticeable advantage when using promises. to the contrary, i found them quite intrusive in my code, what with those deferreds and other concepts that are put on top of asynchronous programming.

作为一个不相关的旁注,我在使用承诺时没有发现任何明显的优势。相反,我发现它们在我的代码中具有相当大的干扰性,因为在异步编程的基础上还有一些延迟和其他概念。

#1


12  

Coffeescript automatically returns the result of the last expressions, so if you don't want it to return the results of the if then you need to add another expressions. In this case, just add return.

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

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

Also, error is already an Error object, so you can just reject it directly.

而且,错误已经是一个错误对象,所以您可以直接拒绝它。

deferred.reject(error)

#2


2  

You can't, exactly. You can either ignore them when not needed (which is the most common thing to do) or provide an explicit alternative by adding an additional statement at the end of the function. I think trying to do this all the time in your code base is fighting a war against the language you cannot win, so my personal recommendation is just accept Mr. Ashkenas's implicit return and go on your merry way.

你不能,没错。您可以在不需要时忽略它们(这是最常见的做法),也可以通过在函数末尾添加一个附加语句来提供显式的替代方法。我认为在你的代码库中一直这么做就是在与你赢不了的语言作战,所以我个人的建议是接受德什肯纳斯先生的含蓄回归,然后继续你的快乐之路。

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

any of those forms will work, but in practice I don't see these commonly

任何一种形式都可以,但在实践中,我不经常看到这些形式

#3


0  

i always do it like this:

我总是这样做:

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

the first return is there to stop execution, not to return a value.

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

you still get an additional (and meaningless) return in your JS from the last line of the callback; to avoid that one, insert an additional return null (or simply return if you prefer that).

您仍然可以从回调的最后一行获得额外的(而且毫无意义的)JS返回;为了避免这种情况,插入一个额外的返回null(如果您喜欢,可以直接返回)。

i'm not sure i like CoffeeScript's implicit return insertion; it might be claimed that 'explicit is better than implicit'. also, it could be argued that the first return shouldn't be a return but another keyword, like, say, stop or finish or somesuch.

我不太喜欢CoffeeScript的隐式返回插入;有人可能会说,“显性比隐性好”。同样,第一次返回不应该是返回,而应该是另一个关键字,比如stop or finish或somesuch。

as an unrelated sidenote, i haven't observed any noticeable advantage when using promises. to the contrary, i found them quite intrusive in my code, what with those deferreds and other concepts that are put on top of asynchronous programming.

作为一个不相关的旁注,我在使用承诺时没有发现任何明显的优势。相反,我发现它们在我的代码中具有相当大的干扰性,因为在异步编程的基础上还有一些延迟和其他概念。