如何获得异步回调'onResponse'的参数?

时间:2019-03-28 12:59:35

标签: java spring asynchronous callback apollo

我正在使用Apollo的查询自动生成功能在Java应用程序中实现GraphQL客户端,到目前为止,我已经能够链接调用并获得所需的数据。问题是,阿波罗让我实现了覆盖ApolloCall.Callback<>()void onResponse(Response response)的匿名方法void onFailure(),但是我找不到找到持有此Response的方法我想要收集并确保有的对象。

这是Java 11上的Spring Boot项目,我尝试使用CompletableFuture,但对它的知识以及如何将其用于这个特殊问题的了解有限,我感到很不走运。我还尝试实现了Apollo应该具有的RxJava支持,但是我无法使用该方法解决依赖关系问题。

我很确定期货会解决这个问题,但是我也不知道怎么做。

  public void getOwnerIdFromClient() {
    client
        .query(getOwnerDbIdQuery)
        .enqueue(
            new ApolloCall.Callback<>() {
              @Override
              public void onResponse(@Nonnull Response<Optional<GetOwnerDbIdQuery.Data>> response) {
                int ownerId =
                    response
                        .data()
                        .get()
                        .entities()
                        .get()
                        .edges()
                        .get()
                        .get(0)
                        .node()
                        .get()
                        .ownerDbId()
                        .get();

                System.out.println("OwnerId = " + ownerId);
              }

              @Override
              public void onFailure(@Nonnull ApolloException e) {
                logger.error("Could not retrieve response from GetOwnerDbIdQuery.", e);
              }
            });
  }

由于我希望在int ownerId之外使用此onResponse,因此这不是一个足够的解决方案。我实际上想进行x次调用,并创建一个我实际获得的所有ID的列表,因为这也可能返回一个空ID,这意味着我需要某种方式来等待它们完成。

2 个答案:

答案 0 :(得分:0)

您是对的,这可以使用期货来完成:

  • 将退货类型更改为Future
  • 通过onResponse完成未来

大约:

public Future<Integer> getOwnerIdFromClient(){
    Future<Integer> result=new CompletableFuture<Integer>();

    client
    .query(getOwnerDbIdQuery)
    .enqueue(
    new ApolloCall.Callback<>(){
        @Override
        public void onResponse(@Nonnull Response<Optional<GetOwnerDbIdQuery.Data>>response){
                // get owner Id
                System.out.println("OwnerId = "+ownerId);
                result.complete(ownerId)
                }

        @Override
        public void onFailure(@Nonnull ApolloException e){
                logger.error("Could not retrieve response from GetOwnerDbIdQuery.",e);result.completeExceptionally(e);


                }
        });

    return result;

}

答案 1 :(得分:0)

如果其他人遇到这个问题,我花了很长时间才弄清楚泛型,但是您可以使用以下方法以通用方式(以避免复制/粘贴所有不同的查询类型)来执行此操作作为单独的类或包装器的功能:

    private <D extends Operation.Data, T, V extends Operation.Variables> CompletableFuture<T> execute(Query<D, T, V> query) {
    CompletableFuture<T> future = new CompletableFuture<>();
    client.query(query).enqueue(new ApolloCall.Callback<>() {
        @Override
        public void onResponse(@NotNull Response<T> response) {
            if (response.hasErrors()) {
                String errors = Objects.requireNonNull(response.getErrors()).stream().map(Object::toString).collect(Collectors.joining(", "));
                future.completeExceptionally(new ApolloException(errors));
                return;
            }
            future.complete(response.getData());
        }

        @Override
        public void onFailure(@NotNull ApolloException e) {
            future.completeExceptionally(e);
        }
    });

    return future;
}

那么应该只是调用的情况

Integer myResult = execute(getOwnerDbIdQuery).get();