11

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.

1
  • 1
    Just don't stack inner classes and use methods for each step? Or use an eventing mechanism. Commented Mar 30, 2015 at 9:39

2 Answers 2

6

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.

Sign up to request clarification or add additional context in comments.

Comments

3

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.
                 });

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.