【发布时间】:2012-01-01 18:37:32
【问题描述】:
我想链接异步休息服务调用并在它们完成时有一个回调。
可以用番石榴做吗?
【问题讨论】:
-
一点点更新,您可以使用专为此目的设计的FluentFuture。它为您提供了来自Futures 的最重要的方法,但使用了流畅的 API。您可以使用静态工厂from 启动链。
我想链接异步休息服务调用并在它们完成时有一个回调。
可以用番石榴做吗?
【问题讨论】:
Futures.chain 在版本 12.0 中被删除。将ListenableFutures 链接在一起的新方法是通过Futures.transform 方法。
https://github.com/google/guava/wiki/ListenableFutureExplained#application
来自 Guava 最新的 javadoc(撰写本文时16.0.1)。
ListenableFuture<RowKey> rowKeyFuture = indexService.lookUp(query);
AsyncFunction<RowKey, QueryResult> queryFunction =
new AsyncFunction<RowKey, QueryResult>() {
public ListenableFuture<QueryResult> apply(RowKey rowKey) {
return dataService.read(rowKey);
}
};
ListenableFuture<QueryResult> queryFuture = transform(rowKeyFuture, queryFunction);
【讨论】:
ListenableFuture f1 = ...; ListenableFuture f2 = transform(f1, fun1, executor); ListenableFuture f3 = transform(f2, fun2, executor); ...。它与 int x1 = ...; int x2 = fun1(x1); int x3 = fun2(x2); ... 这样的函数调用链并没有什么不同。您无需计算价值,而是计算期货。您可以通过在需要之前声明这些部件来避免任何嵌套。 +++ 你可以使用“提取局部变量”来做到这一点,但直接这样做更简单明了。
您可以使用Futures.chain 链接ListenableFutures:
final ListeningExecutorService service1 = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(16));
final ListeningExecutorService service2 = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(16));
ListenableFuture<String> service1result = service1.submit(new Callable<String>() {
@Override
public String call() throws Exception {
return "service1result";
}
});
ListenableFuture<String> service2result = Futures.chain(service1result, new Function<String, ListenableFuture<String>>() {
@Override
public ListenableFuture<String> apply(final @Nullable String input) {
return service2.submit(new Callable<String>() {
@Override
public String call() throws Exception {
return Joiner.on(" -> ").join(input, "service2result");
}
});
}
});
System.out.format("Result: %s\r\n", service2result.get());
上面代码在终端的输出:
> run-main training.Training
[info] Compiling 1 Java source to /home/remeniuk/projects/guava-training/target/scala-2.9.1/classes...
[info] Running training.Training
Result: service1result -> service2result
【讨论】:
Futures.chain 不再可用。另一种方法是使用Futures.transform。