- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试了解 Java 8 中的 CompletableFuture。作为其中的一部分,我正在尝试进行一些 REST 调用以巩固我的理解。我正在使用这个库进行 REST 调用:https://github.com/AsyncHttpClient/async-http-client .
请注意,此库会为 GET 调用返回一个 Response 对象。
以下是我正在尝试做的事情:
构建 UserPost 对象的集合,每个对象都有一个 User 对象和用户发布的帖子列表。
public class UserPosts {
private final User user;
private final List<Post> posts;
public UserPosts(User user, List<Post> posts) {
this.user = user;
this.posts = posts;
}
@Override
public String toString() {
return "user = " + this.user + " \n" + "post = " + posts+ " \n \n";
}
我目前的实现方式如下:
package com.CompletableFuture;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.asynchttpclient.Response;
import com.http.HttpResponse;
import com.http.HttpUtil;
import com.model.Post;
import com.model.User;
import com.model.UserPosts;
/**
* Created by vm on 8/20/18.
*/
class UserPostResponse {
private final User user;
private final Future<Response> postResponse;
UserPostResponse(User user, Future<Response> postResponse) {
this.user = user;
this.postResponse = postResponse;
}
public User getUser() {
return user;
}
public Future<Response> getPostResponse() {
return postResponse;
}
}
public class HttpCompletableFuture extends HttpResponse {
private Function<Future<Response>, List<User>> userResponseToObject = user -> {
try {
return super.convertResponseToUser(Optional.of(user.get().getResponseBody())).get();
} catch (Exception e) {
e.printStackTrace();
return null;
}
};
private Function<Future<Response>, List<Post>> postResponseToObject = post -> {
try {
return super.convertResponseToPost(Optional.of(post.get().getResponseBody())).get();
} catch (Exception e) {
e.printStackTrace();
return null;
}
};
private Function<UserPostResponse, UserPosts> buildUserPosts = (userPostResponse) -> {
try {
return new UserPosts(userPostResponse.getUser(), postResponseToObject.apply(userPostResponse.getPostResponse()));
} catch (Exception e) {
e.printStackTrace();
return null;
}
};
private Function<User, UserPostResponse> getPostResponseForUser = user -> {
Future<Response> resp = super.getPostsForUser(user.getId());
return new UserPostResponse(user, resp);
};
public HttpCompletableFuture() {
super(HttpUtil.getInstance());
}
public List<UserPosts> getUserPosts() {
try {
CompletableFuture<List<UserPosts>> usersFuture = CompletableFuture
.supplyAsync(() -> super.getUsers())
.thenApply(userResponseToObject)
.thenApply((List<User> users)-> users.stream().map(getPostResponseForUser).collect(Collectors.toList()))
.thenApply((List<UserPostResponse> userPostResponses ) -> userPostResponses.stream().map(buildUserPosts).collect(Collectors.toList()));
List<UserPosts> users = usersFuture.get();
System.out.println(users);
return users;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
但是,我不确定我这样做的方式是否正确。更具体地说,在 userResponseToObject
和 postResponseToObject
函数中,我在 Future 上调用 get()
方法,这将是阻塞的。
有没有更好的方法来实现这个?
最佳答案
如果您打算使用 CompletableFuture
,您应该使用 async-http-client 库中的 ListenableFuture
。 ListenableFuture
可以转换为 CompletableFuture
。
使用 CompletableFuture
的优点是您可以编写处理 Response
对象的逻辑,而无需了解任何有关 futures 或线程的知识。假设你写了以下 4 个方法。 2 发出请求和 2 解析响应:
ListenableFuture<Response> requestUsers() {
}
ListenableFuture<Response> requestPosts(User u) {
}
List<User> parseUsers(Response r) {
}
List<UserPost> parseUserPosts(Response r, User u) {
}
现在我们可以编写一个非阻塞方法来检索给定用户的帖子:
CompletableFuture<List<UserPost>> userPosts(User u) {
return requestPosts(u)
.toCompletableFuture()
.thenApply(r -> parseUserPosts(r, u));
}
以及为所有用户读取所有帖子的阻止方法:
List<UserPost> getAllPosts() {
// issue all requests
List<CompletableFuture<List<UserPost>>> postFutures = requestUsers()
.toCompletableFuture()
.thenApply(userRequest -> parseUsers(userRequest)
.stream()
.map(this::userPosts)
.collect(toList())
).join();
// collect the results
return postFutures.stream()
.map(CompletableFuture::join)
.flatMap(List::stream)
.collect(toList());
}
关于java - 子请求的 CompletableFuture,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51954848/
我的应用程序中有 3 种不同的方法。全部返回CompletableFuture .我想并行执行方法 1 和 2。完成方法 1 和 2 后,我想使用方法 1 和 2 返回值的参数触发方法 3。 代码示例
我正在尝试加快对多个 API 的调用。 在下面的代码中,getFilteredEvents是当前同步版本。我有这样的感觉 map(x -> x.getFilteredEvents(eventResea
Q1。我的理解是,如果 future 正常或异常完成,就会调用 completableFuture.handle 。但是超时情况又如何呢? 第二季度。在哪里检查 completableFuture 的
我不明白这里发生了什么 CompletableFuture/supplyAsync。 如果我从先前实例化的 CompletableFuture 对象调用 supplyAsync 方法,它永远不会完成:
我有一个返回 CompletableFuture 的异步方法。 private CompletableFuture asyncA(..) 我公开了一个必须返回 CompleteableFuture 的
我在项目中找到了这段代码: int threadCount = 10; CompletableFuture[] futures = new CompletableFuture[threadCount]
让我们举个例子:我们有四种方法: CompletableFututre loadAndApply(SomeObject someObject); CompletableFuture loadData(
我有一个可完成的 future (future1),它创建了 10 个可完成的 future (futureN)。只有当所有 futureN 都完成时,有没有办法将 future1 设置为完成? 最佳
我想编写一个返回 CompletableFuture 的异步方法. future 的唯一目的是跟踪方法何时完成,而不是其结果。返回CompletableFuture会更好吗?或 Completable
我正在对我的数据库进行多次异步调用。我将所有这些异步调用存储在 List> list 上.我想一起收集所有结果,所以我需要等待所有这些调用完成。 一种方法是创建一个 CompletableFuture
我正在尝试使用 CompletableFuture 链接一些文件处理程序,它应该返回 CompletableFuture : CompletableFuture allGen = loadFile1(
我有 2 个 CompletableFuture。 task2 只能在 task1 完成后启动。然后,我需要等待所有任务完成。在下面的代码中,程序在 task1 结束后结束。 task2 开始但未完成
我有 2 个 CompletableFuture。 task2 只能在 task1 完成后启动。然后,我需要等待所有任务完成。在下面的代码中,程序在 task1 结束后结束。 task2 开始但未完成
我很难弄清楚这一点,并且可以向那些比我更有经验和知识的人寻求帮助。 基本问题是我需要获取对象列表,然后对于返回的每个对象,获取一些详细信息,并将详细信息缝合到对象中。我希望在这方面保持高效;我需要首先
我目前正在使用 CompletableFuture supplyAsync() 方法将一些任务提交到公共(public)线程池。这是代码片段的样子: final List>> completableF
为什么是CompletableFuture.allOf声明为 CompletableFuture而不是返回结果集合或其他东西?我认为制作 CompletableFuture.anyOf 是个好主意返回
我没有看到处理具有异步结果的异常的明显方法。 例如,如果我想重试一个异步操作,我会期待这样的事情: CompletionStage cf = askPong("cause error").handle
比如我有这样的方法: public CompletableFuture getPage(int i) { ... } public CompletableFuture getDocument(
我正在调用一个返回 CompletableFuture 的服务。 输出结构如下。 Class Output { public String name; public Integer a
我正在尝试转换 List>至CompletableFuture> .当您有许多异步任务并且需要获取所有这些任务的结果时,这非常有用。 如果其中任何一个失败,那么最终的 future 将失败。这就是我的
我是一名优秀的程序员,十分优秀!