2012-06-07 72 views
0

假设我需要从我的方法返回一个承诺,这取决于外部资源和一些计算。我想象的是这样的:构建复杂的承诺

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

我可以用什么callWhenReady?这基本上就像jQuery.promise()的行为。

回答

2

我想你想F.Promise.map(播放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); 
        } 
       } 
      }) 
     ); 
    } 

这似乎从你的代码,您使用的是较早版本的播放,但是我觉得你还是应该只能够取代callWhenReadymap(并将Integer类型参数添加到您的回调函数中)。

0

我不知道我完全理解你的问题,但如果你想要做一个异步操作WS,并返回结果,这是做它的方式:

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(); 

现在你可以做对响应进行一些计算,并返回结果。

+0

我想用另一种计算来编写WS承诺,并将构图作为新的未来返回。请参阅https://github.com/ripper234/BTCtoX/blob/d8af7fa07bfe7a0a33ce7e3899fde7ba4193ec2c/app/controllers/Application.java - “tobtc()”调用两个Web API。现在的缺点是每个API都不是完全异步的,并在等待WS HTTP调用时浪费一个工作线程。 – ripper234

+0

东西必须监听这些WS HTTP调用,而在java中这是一个阻塞操作。我不认为play有任何其他机制可以解决这个问题,除此之外就是在单独的线程中完成它。正如我所看到的,如果你同时开始大量的工作,这只会是一个问题。 – aaberg

+0

玩了WS.url(url).getAsync,我想用一个继续来执行我的代码。 Play已经完成了这项设计,以节省工作线程。 – ripper234