3

抱歉,我是 Play Framework 的新手。

我将它与 Java API 一起使用。

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

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

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

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

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

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

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

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

4

1 回答 1

6

您可以使用平面图来实现这一点。由于匿名接口,Java 中的语法有点笨拙(Java 8 和 lambdas 会变得更好)。Promise<T>.flatMap接受 aFunction<T, Promise<U>>并将返回 a 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()它接受列表Promise<T>并返回 a Promise<List<T>>,以便您可以对所有到达的值做出反应。

于 2013-11-09T21:04:28.273 回答