Created
January 10, 2012 22:55
-
-
Save vitaly/1591720 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Lets say you have f1, f2, f3 - functions provided by some API that you can't change | |
# and they use the standard (err, res...) callback scheme | |
# then suppose you need to call 3 of them one after the other | |
# the usual js way will be this: | |
foo = (params, callback) -> | |
f1 something, (err, res) -> | |
if err | |
callback err | |
else | |
f2 something, (err, res) -> | |
if err | |
callback err | |
else | |
f3 something, (err, res) -> | |
if err | |
callback err | |
else | |
callback err, something(res) | |
# and this is how we call this func | |
foo params, (err, res) -> | |
if err | |
do_error err | |
else | |
do_ok res | |
## first lets try to refactor the error handling | |
error_handler = (errcallback, callback) -> | |
(err, res...) -> | |
if err | |
errcallback err | |
else | |
callback res... | |
foo = (params, callback) -> | |
f1 something, error_handler callback, (res) -> | |
f2 something, error_handler callback, (res) -> | |
f3 something, error_handler callback, (res) -> | |
callback null, something(res) | |
# MUCH better ;) | |
#usage still the same | |
foo params, (err, res) -> | |
if err | |
do_error err | |
else | |
do_ok res | |
## now lets try to rewrite with emiter | |
with_emiter = (em, callback) -> | |
(err, res...) -> | |
if err | |
em.emit "error", err | |
else | |
callback res... | |
foo = (params, callback) -> | |
em = new EventEmitter | |
f1 something, with_emiter em, (res) -> | |
f2 something, with_emiter em, (res) -> | |
f3 something, with_emiter em, (res) -> | |
callback res | |
em | |
foo params, (res) -> | |
do_ok res | |
.on "error", (err) -> | |
do_error err | |
# with jQuery Deferred | |
deferred = (d, callback) -> | |
(err, res...) -> | |
if err | |
d.reject err | |
else | |
callback res... | |
# if we can't have all the callbacks sharing context with 'd' we will have to pass it around | |
# like callback d, res... in deferred and having deferred d, (d, res) -> in foo | |
foo = (params, d = $.Deferred()) -> | |
f1 something, deferred d, (res) -> | |
f2 something, deferred d, (res) -> | |
f3 something, deferred d, (res) -> | |
d.resolve res | |
d | |
d = foo | |
d.done (res) -> | |
do_ok res | |
d.error (err) -> | |
do_error err | |
# enother try, this time lets try to use deferrads for success too | |
deferr = (func, args...) -> | |
d = $.Deferred() | |
func args..., (err, res...) -> | |
if err | |
d.reject err | |
else | |
d.resolve res... | |
d | |
foo = (params) -> | |
d = $.Deferred() | |
d1 = deferr f1, something | |
d1.fail (err) -> | |
d.reject(err) | |
d.done (res) -> | |
d2 = deferr f2, something | |
d2.fail (err) -> d1.reject err | |
f2.done (res) -> | |
d3 = deferr f3, something | |
d3.fail (err) -> d2.reject err | |
d3.done (res) -> | |
d.resolve res | |
d | |
# AGAIN | |
deferr = (d, func, args...) -> | |
d2 = $.Deferred() | |
func args..., (err, res...) -> | |
if err | |
d.reject err | |
else | |
d2.resolve res... | |
d2 | |
foo = (params) -> | |
d = $.Deferred() | |
deferr(d, f1, something).done (res) -> | |
deferr(d, f2, something).done (res) -> | |
deferr(d, f3, something).done (res) -> | |
d.resolve(res) | |
# another | |
deferred = (errd) -> | |
d = $.Deferred() | |
callback = (err, res...) -> | |
if err | |
errd.reject err | |
else | |
d.resolve res... | |
callback.done = _.bind(d.done, d) | |
callback | |
foo = (params) -> | |
d = $.Deferred | |
f1 something, deferred(d).done (res) -> | |
f2 something, deferred(d).done (res) -> | |
f3 something, deferred(d).done (res) -> | |
d.resolve res | |
d |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment