Clean way in GWT/Java to wait for multiple asynchronous events to finish Clean way in GWT/Java to wait for multiple asynchronous events to finish java java

Clean way in GWT/Java to wait for multiple asynchronous events to finish


I wrote two classes that solve this problem on my project. Basically, each individual callback registers with a parent. The parent waits for each child callback to complete, then fires off it's own handleSuccess().

The client code looks like this:

public void someGwtClientSideMethod() {    SomeServiceAsync someService = GWT.create(SomeService.class);    ParallelCallback fooCallback = new ParallelCallback();    ParallelCallback barCallback = new ParallelCallback();    ParentCallback parent = new ParentCallback(fooCallback, barCallback) {        public void handleSuccess() {            doSomething(getCallbackData(1), getCallbackData(2));        }    };    someService.foo(fooCallback);    someService.bar(barCallback);}

I wrote a post explaining it here: Parallel Asynchronous Calls in GWT. The implementation for these two classes is linked from that post (sorry, can't give links here because I'm a newbie user - not enough karma to include more than one link!).


Like @Epsen says, Future is probably what you want. Unfortunately, I don't believe Futures are GWT-compatible. The gwt-async-future project claims to bring this functionality to GWT, though I've never tried it. It may be worth a look.


I've struggled with this myself, and I've used several methods- the 'chain' one just gets ugly (but can be improved if you create classes instead of inline classes for each method).

A variant of your own version works well for me:

int outstandingCalls = 0;{outstandingCalls++; AjaxLoader.loadApi("books", "0", new Runnable(){    public void run() {        ready();    }}, null);outstandingCalls++;AjaxLoader.loadApi("search", "1", new Runnable(){    public void run() {        ready();    }}, null);outstandingCalls++;loginService.login(GWT.getHostPageBaseURL(), new AsyncCallback<LoginInfo>() {    public void onSuccess(LoginInfo result) {        ready();    }    // Be sure to decrement or otherwise handle the onFailure});}private void ready() {if (--outstandingCalls > 0) return;// Everything loaded}

All I did was create a counter for the number of calls I'm going to do, then each async result calls ready() (be sure to do this on the failure methods too, unless you're going to do something different)

In the ready method, I decrement the counter and see if there are still outstanding calls.

It's still ugly, but it lets you add calls as needed.