How to avoid implicit "return" in coffeescript in conditional expressions?

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

eg:.

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 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 if / else is not returned (i.e. β†’ return <- in the compiled code)

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

+12
javascript promise deferred coffeescript
Mar 18 '13 at 4:04 on
source share
3 answers

Coffeescript automatically returns the result of the latest expressions, so if you do not want it to return if results, you need to add another expression. In this case, just add return .

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

In addition, error already an error object, so you can simply reject it directly.

 deferred.reject(error) 
+12
Mar 18 '13 at 4:07
source share

You cannot, for sure. You can either ignore them when they are not needed (which is most often used), or provide an explicit alternative by adding an additional operator at the end of the function. I think that trying to do this all the time in your code base is fighting against a language that you cannot win, so my personal recommendation just accepts the implicit return of Mr. Ashkenas and continues your fun journey.

 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 these forms will work, but in practice I don't see them usually

+2
Mar 18 '13 at 4:12
source share

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 should stop execution, and not return a value.

you still get an extra (and meaningless) return in your JS from the last line of the callback; to avoid this, add an extra return null (or just return if you want to).

I'm not sure I like the implicit insertion in CoffeeScript; it can be argued that "explicit is better than implicit." In addition, it can be argued that the first return should not be return , but with another keyword, for example, stop or finish or somesuch.

as an unrelated side element, I did not notice any noticeable benefits when using promises. on the contrary, I found them rather intrusive in my code that with these deferred and other concepts that are put on top of asynchronous programming.

0
Jul 21 '14 at 10:27
source share



All Articles