Someone more knowledgable than me can correct me if I'm wrong, but
here's my understanding.
The compiler already analyzes your code to do things like dead code
removal. In other words, it already removes code from the output that
it can prove will never be invoked. The support for runAsync is
similar in that the compiler constructs some kind of call graph of
your code and any subgraph that's entirely behind a call to runAsync
gets broken out into a separate "fragment". Each fragment is then
separately downloadable.
To more directly answer your question, the definition of startWorking
should be separated from the main module but method2 won't be. Any
code that's called from startWorking and nowhere else should also be
separated from the main module, but anything that's called from
method2 would necessarily be included with the main module. The
analysis gets more complicated as you add calls to runAsync, but the
traffic I've seen describing the design of runAsync makes it sound
like the compiler should be able to handle any combination (barring,
of course, any bugs that might still be lingering).
Ian
That's it exactly.
> Any
> code that's called from startWorking and nowhere else should also be
> separated from the main module, but anything that's called from
> method2 would necessarily be included with the main module. The
> analysis gets more complicated as you add calls to runAsync, but the
> traffic I've seen describing the design of runAsync makes it sound
> like the compiler should be able to handle any combination (barring,
> of course, any bugs that might still be lingering).
It's a new tool, so we'll have to figure out the best coding idioms to
use it. I believe, though, that you're best off if you can factor
your code so that you don't have much of the same code reachable via
two runAsync calls. Instead, make one runAsync call, but let it take
a callback as a parameter.
That is, don't do this:
void method1() {
GWT.runAsync(/* ..method1 stuff.. */);
}
void method2() {
GWT.runAsync(/* ..method2 stuff, similar to method1 stuff.. */);
}
Instead, do it like this:
class MyModule {
interface Callback { ... }
static void runAsync(final Callback cb) {
GWT.runAsync(new RunAsyncCallback() {
void onSuccess() { cb.onSuccess(); }
void onFailure() { Window.alert("doh!"); }
}
}
void method1() {
MyModule.runAsync(new Callback() { /*..method1 stuff..*/ });
}
void method2() {
MyModule.runAsync(new Callback() { /*..method2 stuff..*/ });
}
The compiler associates code fragments with calls to runAsync. So,
the idea here is that you help the compiler identify a good chunk of
stuff to associate with the runAsync call in MyModule.runAsync. If
you instead had method1 and method2 each call runAsync individually,
then the compiler would not be able to assign code to each of those
calls.
If you try this idiom, do make sure that you make your own callback
interface rather than usingRunAsyncCallback directly. You want the
compiler to know that, within MyModule.runAsync, the call to
cb.onSuccess() will only call the callbacks related to MyModule, not
to any other callback in the system.
Lex Spoon