如何使用Java在Play框架中嵌套Promise?

时间:2013-11-07 09:52:48

标签: java playframework akka playframework-2.2

抱歉,我是Play Framework的新手。

我在Java API中使用它。

假设我想让控制器操作运行某种导入并在导入完成后显示结果。

导入需要与第三方服务进行昂贵的HTTP通信(从3个URL获取数据,处理数据,在处理完3个资源后更新数据库)。

所以我想将导入本身实现为控制器中的Promise(Controller不应该知道导入实现)。

然后我想运行从URL获取数据并在3个并行线程中处理。我认为将它作为3个单独的Promise来实现会很好。

只有在(并且如果)所有三个承诺成功完成时,才应更新数据库。

最后,数据库更新后应通知控制器。

我能够将整个导入实现为Promise,但我不知道如何实现嵌套的promises。

如果我尝试使用错误的方法,你能建议如何实施或纠正我吗?

1 个答案:

答案 0 :(得分:6)

您可以使用flatmap实现此目的。由于匿名接口(Java 8和lambdas会更好),Java中的语法遗憾地有点笨拙。 Promise<T>.flatMap接受Function<T, Promise<U>>并返回Promise<U>。这意味着您可以嵌套来自所有三个操作的flatMaps,并使用flatmap收集它们,如下所示:

final Promise<String> promise1 = Promise.pure("one");
final Promise<String> promise2 = Promise.pure("two");
final Promise<String> promise3 = Promise.pure("three");

Promise<String> allThreeCombined = promise1.flatMap(new Function<String, Promise<String>>() {
     @Override
     public Promise<String> apply(final String result1) throws Throwable {
         return promise2.flatMap(new Function<String, Promise<String>>() {
             @Override
             public Promise<String> apply(final String result2) throws Throwable {
                 return promise3.map(new Function<String, String>() {
                     @Override
                     public String apply(String result3) throws Throwable {
                         return result1 + result2 + result3;
                     }
                 });
             }
         });
     }
}); 

如果您正在获取的每个不同内容没有特殊含义 - 例如,如果要将它们视为值列表,您还可以使用Promise.sequence()接受{{1}列表}并返回Promise<T>,以便您可以对到达的所有值做出反应。