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.