ripper234
ripper234

Reputation: 230038

Building complex promises in Play

Supposed I need to return a promise from my method, that depends on an external resource and some calculation. What I imagine is something like:

Promise<Integer> foo() {
  return WS.url(url)
    .getAsync()
    .callWhenReady(new Function<HttpResponse>(){
      Integer parse(HttpResponse response) {
        // parsing business logic 
        // ...
        int parsed = ...;
        return parsed;
      }
  });
} 

What can I use for callWhenReady? This is essentially just like jQuery.promise() behaves.

Upvotes: 0

Views: 1527

Answers (2)

Kenji Matsuoka
Kenji Matsuoka

Reputation: 506

I think you want F.Promise.map (Play 2.0.2):

    /**
     * Maps this promise to a promise of type <code>B</code>.  The function <code>function</code> is applied as
     * soon as the promise is redeemed.
     *
     * Exceptions thrown by <code>function</code> will be wrapped in {@link java.lang.RuntimeException}, unless
     * they are <code>RuntimeException</code>'s themselves.
     *
     * @param function The function to map <code>A</code> to <code>B</code>.
     * @return A wrapped promise that maps the type from <code>A</code> to <code>B</code>.
     */
    public <B> Promise<B> map(final Function<A, B> function) {
        return new Promise<B>(
            promise.map(new scala.runtime.AbstractFunction1<A,B>() {
                public B apply(A a) {
                    try {
                        return function.apply(a);
                    } catch (RuntimeException e) {
                        throw e;
                    } catch(Throwable t) {
                        throw new RuntimeException(t);
                    }
                }
            })
        );
    }

It seems from your code that you're using an earlier version Play, but I think you should still just be able to replace callWhenReady with map (and add an Integer type parameter to your callback function).

Upvotes: 2

aaberg
aaberg

Reputation: 2273

I'm not sure I fully understand your question, but if you want to do an asynchronous WS operation, and return the result, this is the way to do it:

F.Promise<WS.HttpResponse> promise = WS.url(url).getAsync();
// The following line corresponds to your callWhenReady. 
// It waits for the result in a non blocking way.
await(promise);

WS.HttpResponse response = promise.get();

now you can do some calculation on the response, and return the result.

Upvotes: 0

Related Questions