我正在实现一个具有延迟值的函数来返回,并且在函数中我有许多嵌套的条件表达式:
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编译器出现这种行为(不需要隐式返回)?
答案 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
而是另一个关键字,例如stop
或finish
或其他关键字。
作为一个不相关的旁注,我在使用承诺时没有观察到任何明显的优势。相反,我发现它们在我的代码中非常具有侵入性,那些deferred
以及其他概念放在异步编程之上。