
com.asayama.gwt.angular.site.examples.client.PromiseExampleDocumentation.html Maven / Gradle / Ivy
GWT Angular supports promise pattern via Java wrapper around AngularJS's
promise framework, which is inspired by
Kris Kowal's Q.
The below example demonstrates how two asynchronous calls are coordinated
by a third, which depends on the outcome of the first two. Promise pattern
makes it easy to establish pipelines of asynchronous calls without having to
write a complex sequence of nested callbacks.
When you click the "Go" button below, first, the user is warned that he must
wait for 1 second to see the outcome of his action. The user's action kicks
off two asynchronous calls, one generates the salutation, "Hello", and the
other generates the name, "World". These two asynchronous calls take
different amount of time to complete. There is a third call, which takes the
results of salutation and name, and formats a greeting. The greeting message
is then displayed to the screen.
View
The view code is straight forward, and has no knowledge of controller's
implementation and its asynchronous nature. It assumes that the greeting
data is or will be provided, hence it calls {{ getGreeting }}
method on the controller to obtain the value to print to the screen.
Controller
Controller takes no action onload, but when the user clicks the "Go" button,
it invokes onClickGo()
method. This method first updates the
greeting caption on screen, letting the user know that the loading of the
data is in progress. Then the method goes on to invoke the getGreeting()
method of GreetingService
object.
This service object is something we wrote for the purpose of demonstrating
the promise pattern in GWT Angular. We will look at the implementation of
this service class shortly, but for now, we'll focus on the handling of
the Promise<String>
object returned by this service call.
The returned object is a promise that, when the promised value is ready, it
would invoke the callback object that you register with this promise object.
In this case, what it promises is that the object of type String
will be returned, signifying the greeting value.
We pass three different callback to this promise. First callback we pass is
the Done
object. This object receives the greeting value, and
updates the screen caption with this value. The second callback is
Notify
object, which listens to the progress of asynchronous calls
and updates the screen to let the user know of the progress. The third
callback is the Fail
, which displays an error message on the
screen if and when the promise fails to deliver the value.
In short, the controller merely knows how to consume the promise value, if
and when it is delivered. It does not know any details about how the values
are obtained.
Service
GreetingService
is the code that handles the complexity of
asynchronously loading the necessary data from the back-end. In this
example, we decided to simulate asynchronous loading of the data rather than
actually setting up live web services. This is because we wanted to focus
on the promise and resolution of the values in the browser, and did not
want to distract you with the design and implementation of web service code.
There are three public methods in this service, getGreeting()
,
which you have already seen being called from the controller, and two others,
getName()
and getSalutation()
. All three public
methods return an object of type Promise
.
getSalutation()
method simulates an asynchronous call by using
a Timer
class in GWT. It schedule a job to run in 1 second,
which returns a string value "Hello" by calling the resolve()
method on the Deferred
object obtained from Q
.
getName()
method also simulates an asynchronous call by using
a Timer
class in GWT. It schedule a job to run in 0.5 seconds,
which returns a string value "World" by calling the resolve()
method on the Deferred
object obtained from Q
.
Note that neither of the getSalutaion()
or getName()
methods are blocking, in a sense that the caller does not have to wait for
these promised string values to become available. They simply return the
Promise
values, so that the caller can later retrieve these
values whenever they become available.
You may recall that the controller for this demo does not call these two
service methods we have so far talked about, but the controller calls the
getGreeting()
method. Let's take a look at it now.
getGreeting()
method uses q.all()
service method
of type Q
, which is injected by AngularJS into our custom
service class. This method allows the parallel execution of promises, and
returns another single promise to be resolved when all promises are ready.
The concept of parallel execution is rather important. If we had executed
these three asynchronous calls in series, then the execution time of the
entire pipeline would have been 1.5 seconds. But because we execute them
in parallel, we can execute them in 1 second, which is the slower of the
two promises that the getGreeting()
depends on.
The purpose of getGreeting()
method is to construct a new
greeting object, given the values of salutation and name. It knows how to
construct this new value, but it does not have to know anything about how
these values are loaded.
Configuration
The following modules are required in the gwt.xml.
The following Maven dependencies are required in the pom.xml.
<dependency>
<groupId>com.asayama.gwt</groupId>
<artifactId>gwt-angular-ng</artifactId>
<version>{{ PROJECT_VERSION }}</version>
</dependency>
You can also browse the full source code on Github.
{{ GITHUB_SOURCE_URL }}/gwt-angular-site/gwt-angular-examples/Promise