One thing that is not obvious at first is that code splitting part of your 
application that performs computation is far from trivial and will sometimes 
require you to change your code in deep ways. That's because you have to 
switch your mindset from "regular linear programming" to "deferred 
execution". That is, if your program looks like this:

int x = foo();
int y = bar(x);
goo(z);

and you want to code-split foo(), then you can no longer call bar() and 
goo() right after having called foo. Instead, you have to call them in the 
onSuccess() of your RunAsyncCallback. 

In the above case it's relatively easy to refactor the code in that fashion, 
but it can become more tricky when you have a deep call stack and the result 
of method calls is returned down to some user you know nothing of. For 
example:

int fooCaller() {
  // do some stuff
  return foo();
}

int barCaller() {
  int y = fooCaller();
  // do some stuff on y
  return bar(y);
}

void gooCaller() {
  int z = barCaller();
  // do some stuff on z
  goo(z);
}

Now codesplitting foo() is an entire different story. You could try to 
refactor the code to eliminate some of the nested calls, but sometimes it's 
impractical or even impossible (say, because fooCaller() is invoked from 
many different places). In that case, what I usually do is to define a 
deferred command interface that let's me wrap the "future execution". For 
example, here I would define:

public interface CommandWithInt {
  public void execute(int param);
}

And then refactor the code using anonymous instances of this interface, and 
making all methods return void:

void fooCaller(final CommandWithInt command) {
  // do some stuff
  GWT.runAsync(new RunAsyncCallback() {
    @Override
    public void onSuccess() {
      command.execute(foo());
    }
    // ...
  }
}

void barCaller(final CommandWithInt command) {
  CommandWithInt callBar = new CommandWithInt() {
    public void execute(int x) {
      // do some stuff on x
      command.execute(bar(x));
    }
  }
  fooCaller(callBar);
}

void gooCaller() {
  CommandWithInt callGoo = new CommandWithInt() {
    public void execute(int y) {
      // do some stuff on y
      goo(y);
    }
  }
  barCaller(callGoo);
}

The way to interpret this is that gooCaller tells barCaller: "Do whatever 
you need to do, when you're done execute callGoo".  In the same way, 
barCaller tells fooCaller: "Do whatever you need to do, when you're done 
execute callBar". 

Hope this helps!

    Philippe

-- 
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-web-toolkit?hl=en.

Reply via email to