Parallel asynchronous calls in GWT

The asynchronous nature of GWT makes for more powerful and usable web applications, but as a developer, it can take a little while to get used to. Here’s one example: imagine a scenario where some client-side class needs to call two service operations before it can do something. Simple, right? In a synchronous world, it would be:

  1. public void someMethod() {
  2.   Service someSerive = new SomeService();
  3.   String str1 =;
  4.   String str2 =;
  5.   doSomething(str1, str2);
  6. }

In GWT, things are necessarily a little trickier. Using the standard RPC plumbing, calls from the client to a remote service are handled asynchronously, via GWT’s AsyncCallback mechanism. For example:

  1. AysncCallback() {
  2.     public void onFailure(Throwable caught) {}
  3.     public void onSuccess(final String str1) {
  4.       // do something here;
  5.     }
  6. });

This is relatively straight-forward. If we wanted to make two calls to some service, however, then do something after both have completed, our first instinct might be to just chain the service calls – e.g. when one service completes, call the second:

  1. public void someGwtClientSideMethod() {
  2.   SomeServiceAsync someService = GWT.create(SomeService.class);
  3. AsyncCallback<String>() {
  4.     public void onFailure(Throwable caught) {}
  5.     public void onSuccess(final String str1) {
  6. AsyncCallback<String>() {
  7.         public void onFailure(Throwable caught) {}
  8.         public void onSuccess(String str2) {
  9.           doSomething(str1, str2);
  10.         }
  11.       });
  12.     });
  13.   }

While this works, it’s not ideal. First, it’s really ugly…and this is just for a case with 2 chained async calls – imagine if you had 3 or 4! Second, it’s slower than it needs to be, since the calls are made serially rather than in parallel.

One obvious solution is to just combine the two service operations into one (an argument for this here) – only one call is made to the server, and you don’t have to bother with the ugly nesting:

  1. public void someGwtClientSideMethod() {
  2.   SomeServiceAsync someService = GWT.create(SomeService.class);
  3.   someService.fooAndBar(new AsyncCallback<FooBarResult>() {
  4.     public void onFailure(Throwable caught) {}
  5.     public void onSuccess(final FooBarResult fbr) {
  6.       doSomething(fbr.getFooResult(), fbr.getBarResult());
  7.     }
  8.   });
  9. }

This is better, but unfortunately combining service operations like this isn’t always possible (or practical). Services may not be under your control…and even if they are, it’s a lot of work to aggregate operations, and could result in a pretty complex/messy service if there are many such combinations.

Another possible solution would be to make the calls in parallel, and then only doSomething() when both service calls return. I developed two classes,ParallelCallback and ParentCallback, for this exact purpose. Using these, the code in the client would look like this:

  1. public void someGwtClientSideMethod() {
  2.   SomeServiceAsync someService = GWT.create(SomeService.class);
  3.   ParallelCallback fooCallback = new ParallelCallback();
  4.   ParallelCallback barCallback = new ParallelCallback();
  5.   ParentCallback parent = new ParentCallback(fooCallback, barCallback) {
  6.     public void handleSuccess() {
  7.       doSomething(getCallbackData(0), getCallbackData(1));
  8.     }
  9.   };
  12. }

Without getting too mired in the implementation guts, essentially each service method has its own ParallelCallback, which is registered with a ParentCallback. When the service has completed, the ParallelCallback then informs the parent it’s done, and when the parent has heard back from each of is children, it calls its own handleSuccess() method, overridden and implemented by you. Return data from the individual service ParallelCallbacks can be extracted using the getCallbackData() method.

While this solution definitely still has some conceptual load, it eliminates the double-AsyncCallback-nesting, so seems a little simpler (to me!) than the chaining solution above. Also, as mentioned, RPC calls are made in parallel, so the overall latency should be less.

Anyway, the code is available here if you’re interested. Let me know what you think, or if you’ve found another better way to solve this issue.



public abstract class ParentCallback {

    /** The number of service calls that have successfully completed. */
    private int doneCount = 0;

    /** The children callbacks for which this parent checks to see if they are done. */
    private ParallelCallback childCallbacks[];

     * Default constructor, passing in all child callbacks for the parent to check if they are done.
    protected ParentCallback(ParallelCallback... callbacks) {
        if (callbacks == null || callbacks.length == 0) {
            throw new RuntimeException("No callbacks passed to parent");

        this.childCallbacks = callbacks;

        for (ParallelCallback callback : callbacks) {

     * Called by the child ParallelCallbacks on completion of the service call. Only when all
     * children have completed does this parent kick off it's on handleSuccess().
    protected synchronized void done() {

        if (doneCount == childCallbacks.length) {


     * Called only when all children callbacks have completed.
    protected abstract void handleSuccess();

     * Get the data from the callback. Should only be called within the handleSuccess() block.
    protected &lt;D extends Object&gt; D getCallbackData(int index) {
        if (index &lt; 0 || index &gt;= childCallbacks.length) {
            throw new RuntimeException("Invalid child callback index");

        return (D) childCallbacks[index].getData();


public class ParallelCallback&lt;T&gt; implements AsyncCallback&lt;T&gt; {

    /** The data that is returned from the service call. */
    private T data;

    /** A reference to the parent callback, which runs when all are complete. */
    private ParentCallback parentCallback;

     * Standard handleSuccess method, which is called when the service call completes.
    public void onSuccess(T t) { = t;

     * Method that can be used by the parent callback to get the data from this service call and
     * process it.
    public T getData() {
        return data;

     * Called by the parent callback, to inject a reference to itself into the child.
    protected void setParent(ParentCallback parentCallback) {
        this.parentCallback = parentCallback;

	 * Handle the error.
    public void onFailure(Throwable arg0) {
        // TODO Auto-generated method stub


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s