Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pattern for cascade/nested asynchronous calls

When working with gwt on client side there is common situation to call asynchronous method with processing in callback method.

asyncService.method(new AbstractAsyncCallback<Number>() {
  @Override
  public void onSuccess(Number num) {
    // do something with number
  }
});

But often encountered situation where need to get result from one asynchronous method, pass to another, etc. That's why we get dirty cascade code, that hard to read.

asyncService.method(new AbstractAsyncCallback<Number>() {
      @Override
      public void onSuccess(Number num) {
        asyncService.method1(num, new AbstractAsyncCallback<String>() {
          @Override
          public void onSuccess(String str) {
             asyncService.method2(str, new AbstractAsyncCallback<Void>() {
               @Override
               public void onSuccess(Void void) {
                 // do something
               }
             });
          }
        });
      }
    });

I know, we can combine this three calls on server side to make separate service method, but what if we need a lot such combinations of different methods? Another concern is to add separate method, that perform functionality that we can get by simple combination of existing ones.

Is there a common pattern to get rid of such code and not change server-side service?

like image 974
mishadoff Avatar asked Oct 06 '22 09:10

mishadoff


1 Answers

You outlined one pattern: a chain of calls. This pattern should be used only if the second call depends on the results of the first call, etc.

If you can execute requests in parallel, you should. One option is a target method that waits for other methods to complete before proceeding. In this example showPerson() will be called twice, but it will execute only once when all data is ready.

Integer age = null;
String name = null;

asyncService.method(new AbstractAsyncCallback<Integer>() {
    @Override
    public void onSuccess(Integer num) {
        age = num;
        showPerson();
    }
});
asyncService.method(new AbstractAsyncCallback<String>() {
    @Override
    public void onSuccess(String n) {
        name = n;
        showPerson();
    }
});

private void showPerson() {
    if (name != null && age != null) {
        myView.showPerson(name, age);
    }
}
like image 130
Andrei Volgin Avatar answered Oct 10 '22 03:10

Andrei Volgin