是否可以使用 Guava 链接异步调用?
Posted
技术标签:
【中文标题】是否可以使用 Guava 链接异步调用?【英文标题】:Is it possible to chain async calls using Guava? 【发布时间】:2012-01-01 18:37:32 【问题描述】:我想链接异步休息服务调用并在它们完成时有一个回调。
可以用番石榴做吗?
【问题讨论】:
一点点更新,您可以使用专为此目的设计的FluentFuture。它为您提供了来自Futures 的最重要的方法,但使用了流畅的 API。您可以使用静态工厂from 启动链。 【参考方案1】: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);
【讨论】:
我正在使用 Futures.transform,但我得到的代码块嵌套了 12 层。有没有办法将其线性化? @Sridhar-Sarnobat 当然,只是“放松”它。创建最里面的未来,将其组合成一个新的变量,等等。 @maaartinus hmmmm 我不确定我明白了。响应正文中的示例会有所帮助 @Sridhar-Sarnobat 这不是我的答案,我不确定它是否是一个好的编辑。我的意思是这样的:ListenableFuture f1 = ...; ListenableFuture f2 = transform(f1, fun1, executor); ListenableFuture f3 = transform(f2, fun2, executor); ...
。它与 int x1 = ...; int x2 = fun1(x1); int x3 = fun2(x2); ...
这样的函数调用链并没有什么不同。您无需计算价值,而是计算期货。您可以通过在需要之前声明这些部件来避免任何嵌套。 +++ 你可以使用“提取局部变量”来做到这一点,但直接这样做更简单明了。
哦,我明白了。它只是提取局部变量。通常我喜欢像你说的那样内联一次性变量。我希望可能会有一个转换,需要一个平面的期货列表,但我想不会。【参考方案2】:
您可以使用Futures.chain
链接ListenableFuture
s:
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
。以上是关于是否可以使用 Guava 链接异步调用?的主要内容,如果未能解决你的问题,请参考以下文章
从Java Future到Guava ListenableFuture实现异步调用