I have java app with sequence of api calls (I'm using retrofit). Currently it looks like pyramid:
mApi.login(request, new Callback<LoginResponse>() {
@Override
public void success(LoginResponse s, Response response) {
mApi.getRoutes(request, new Callback<RoutesResponse>() {
@Override
public void success(RoutesResponses, Response response) {
...
}
@Override
public void failure(RetrofitError error) {}
}
}
@Override
public void failure(RetrofitError error) {}
});
Are there some libraries to avoid callback hell? like TwoStep or Q in javascript.
We can avoid the callback hell with the help of Promises. Promises in javascript are a way to handle asynchronous operations in Node. js. It allows us to return a value from an asynchronous function like synchronous functions.
This is affectionately known as callback hell. The cause of callback hell is when people try to write JavaScript in a way where execution happens visually from top to bottom. Lots of people make this mistake!
So, it is quite evident that the presence of callbacks in the code makes it harder to maintain or further write the code. It poses a hurdle in understanding the flow of code and is a major drawback when debugging the entire code.
They can handle multiple asynchronous operations easily and provide better error handling than callbacks and events. In other words also, we may say that, promises are the ideal choice for handling multiple callbacks at the same time, thus avoiding the undesired callback hell situation.
As long as you are sequencing just the API calls, you can employ Retrofit's RxJava support by using Observables instead of callbacks and tying them together with the Rx stream support. I mostly use .flatmap() function to convert result of one API call to another. In your case, it would like something like this:
First I will be using the Observable version of the calls instead of the ones with callbacks, which will be:
Observable<LoginResponse> login(loginRequest);
Observable<RoutesResponse> getRoutes(routesRequest);
After we have these two functions in our API, we can tie them together with RxJava streams. Here is one without error checking, I am writing this on the go to show as a quick example:
public Observable<RoutesResponse> rxGetRoutes(loginRequest, routesRequest) {
final YourAPI mAPI = YourApiProvider.getInstance();
return mAPI.login(loginRequest)
//using flatmap to convert one answer to another answer
.flatmap( (Func1) LoginResponse -> {
return mAPI.getRoutes(routesRequest);
});
}
You can now observe and subscribe to the returned Observable of this function as normal, after learning RxJava a bit:
rxGetRoutes(loginReq, routesReq)
.observeOn(//the thread you want to observe on)
.subscribe( new Subscriber<RoutesResult>() {
@Override
//the functions of Subscriber you need to override
//where you can also check for errors
//Check RxJava documentation after your IDE completes this area.
});
Using lambda expressions
will get rid of this kind of callback hell.But, since Callback<T>
interface consists of 2 abstract methods, you cannot directly use lambdas. This is where RxJava kicks in. RxJava introduces more functional way and enables you to use functional interfaces where you can use lambda to reduce callback hell.
RxJava is a Java VM implementation of ReactiveX (Reactive Extensions): a library for composing asynchronous and event-based programs by using observable sequences...
Here is some resources about RxJava and lambda.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With