2012-06-07 106 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