Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid callback hell in Java?

Tags:

java

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.

like image 591
Alexey Ryazhskikh Avatar asked Mar 30 '15 08:03

Alexey Ryazhskikh


People also ask

How can callback hell be avoided?

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.

What causes callback hell?

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!

What is the drawback of callback hell?

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.

How are promises more superior than callbacks How do promises solve the issue of callback hell?

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.


2 Answers

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.
                 });
like image 182
Leod Avatar answered Sep 30 '22 00:09

Leod


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.

  • Grokking RxJava, Part 1: The Basics
  • Monads: Your App as a Function
like image 41
bhdrkn Avatar answered Sep 30 '22 00:09

bhdrkn