Reputation: 11733
I'm not so experienced/elegant programmer. I hope my question is understandable.
I have used java/c++ for most part of my life so my mind is object oriented. Then I learned python and I enjoyed very much functional mind. Now I'm approaching js. It is challenging because it is function based (and I liked it a lot), functional (with underscore I have a lot of pythonic iterutils
methods) and asynchronous (it hurts).
A lot of time I have some back-end sync procedural flow like:
if exist(user):
foo(user)
# ok
else:
add(user)
# user added
Now I have to handle this with the so called callback hell:
exists(user, function(userExist) {
if( userExist ) {
foo( user, function(fooResult) {
/* ok */
});
} else {
add( user, function(addResult) {
/* user added */
});
}
});
Sometimes the controls are more nested: check for token, if token is valid check for user exists, if user exists check for valid parameters, then check for no error in foo on user, etc…
Those controls are simply synchronous and imperative-like. Nothing else to say. While with sync language like python I can handle this is (not elegant but at least) readable code with the use of small function that returns values , with javascript I don't know how to refactor things in readable small function. All functions I wrote does not have any return
statements but just callback(something_weird_defined_in_caller_function)
and I lost myself.
I don't think that promises are good on my case because are more for piping events, IIUC. So I'm looking for some pattern using async
library to handle this case:
- continue to execute functions in series only if the previous one succeeded.
Please any help will be appreciated.
Upvotes: 0
Views: 149
Reputation: 664548
I don't think that promises are good on my case because are more for piping events, IIUC
No. Promises don't represent a stream of events to pipe, but a single result that will arrive later (asynchronously). This is exactly what they were made for, and they will give you imperative-like looking code (instead of a nesting callback hell).
Admittedly, you still need nesting for control structures. The code that you presented won't look much different except for the callbacks going into .then()
calls, and promises being return
ed.
However, you can also use exceptions for control flow. Instead of using exists
that returns a Promise<boolean>
, you could use a find
function that returns a Promise<User>
which would get rejected when the user doesn't exist. It could be used like
find(user).then(function(/*user*/) {
return foo(user) /* .then(function(fooResult) {
…
}); */
}).catch(UserNotFoundError, function(e) {
return add(user) /* .then(function(addResult) {
…
}); */
});
Which of those to choose is debatable, rejections should be exceptional.
Upvotes: 1