如何知道所有异步HTTP调用已完成

已付Pr0:

我试图弄清楚如何确定我发出的所有异步HTTP GET请求是否都已完成,以便可以执行另一种方法。对于上下文,我有一些类似于以下代码的内容:

public void init() throws IOException {
    Map<String, CustomObject> mapOfObjects = new HashMap<String, CustomObject>();
    ObjectMapper mapper = new ObjectMapper();

    // some code to populate the map

    mapOfObjects.forEach((k,v) -> {
        HttpClient.asyncGet("https://fakeurl1.com/item/" + k, createCustomCallbackOne(k, mapper)); 
        // HttpClient is just a wrapper class for your standard OkHTTP3 calls, 
        // e.g. client.newcall(request).enqueue(callback);
        HttpClient.asyncGet("https://fakeurl2.com/item/" + k, createCustomCallbackTwo(k, mapper));
    });
}


private createCustomCallbackOne(String id, ObjectMapper mapper) {
    return new Callback() {
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            if (response.isSuccessful()) {
                try (ResponseBody body = response.body()) {
                    CustomObject co = mapOfObjects.get(id);
                    if (co != null) {
                        co.setFieldOne(mapper.readValue(body.byteStream(), FieldOne.class))); 
                    }                       
                } // implicitly closes the response body                
            }    
        }

        @Override
        public void onFailure(Call call, IOException e) {
            // log error                
        }
    }
}

// createCustomCallbackTwo does more or less the same thing, 
// just sets a different field and then performs another 
// async GET in order to set an additional field

那么监视所有这些异步调用以确保它们已经完成的最佳/正确方法是什么,我可以对存储在地图内的对象执行另一种方法?

吉米·B:

最简单的方法是保持“运行中”请求的数量。对于排队的每个请求,将其递增,在回调末尾将其递减。当/如果计数为0,则完成任何/所有请求。使用信号量或计数锁,您可以wait使其不轮询而变为0。

请注意,回调在单独的线程上运行,因此您必须提供某种同步。

如果要为每个请求创建一个新的回调,则可以使用如下所示的内容:

public class WaitableCallback implements Callback {

  private boolean done;
  private IOException exception;

  private final Object[] signal = new Object[0];

  @Override
  public void onResponse(Call call, Response response) throws IOException {
      ...
      synchronized (this.signal) {
        done = true;
        signal.notifyAll();
      }
  }

  @Override
  public void onFailure(Call call, IOException e) {
    synchronized (signal) {
      done = true;
      exception = e;
      signal.notifyAll();
    }
  }

  public void waitUntilDone() throws InterruptedException {
    synchronized (this.signal) {
      while (!this.done) {
        this.signal.wait();
      }
    }
  }

  public boolean isDone() {
    synchronized (this.signal) {
      return this.done;
    }
  }

  public IOException getException() {
    synchronized (this.signal) {
      return exception;
    }
  }

}

为每个请求创建一个实例,并将其放入例如中List<WaitableCallback> pendingRequests

然后,您可以等待所有请求完成:

for ( WaitableCallback cb : pendingRequests ) {
  cb.waitUntilDone();
}
// At this point, all requests have been processed.

但是,您可能不应该为每个请求创建一个新的相同的回调对象。回调方法将Call传递的参数作为参数,以便代码可以对其进行检查以找出正在处理的请求。在您的情况下,您似乎甚至不需要它。因此,对应以相同方式处理的请求使用单个Callback实例。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

当我知道所有异步调用都已完成时,如何运行回调?

我如何知道页面上的所有异步调用何时完成(Parse Cloud函数)?

如何知道所有异步功能何时完成?

在所有异步HTTP调用完成之前如何显示加载指示器-Angular

Node.js 如何知道所有异步功能何时完成?

循环中的所有异步调用完成后,如何调用函数?

完成所有异步Http请求后执行功能

你如何等待所有异步调用在Java中完成?

如何等待所有异步调用完成

如何确保在所有异步函数完成后再次调用间隔函数?

如何等待所有异步完成?

如何使Parallel等待所有异步任务完成?

等待所有异步方法完成

需要知道所有异步操作何时完成

如何在嵌套的foreach中继续操作之前确保所有异步调用完成

如何进行循环等待所有异步功能完成。异步函数里面有多个异步函数

如何知道所有Angular2 HTTP调用何时完成

如何使Jest在期待断言之前等待所有异步代码完成执行

如何在Node.js中等待所有异步任务完成?

在加载数据之前完成所有异步请求?

完成所有异步任务后,从NodeJS脚本退出

如果您知道任务已完成,可以调用task.Result生成异步方法吗?

多个嵌套的forEach循环中的所有异步操作完成后,如何解决Promise?

等待完成异步 lambda 表达式中的所有异步方法

如何知道所有 $http 调用是否结束 - AngularJS

具有异步lambda的Parallel.ForEach等待所有迭代完成

如何知道异步调用是否完成?(HackerNews评论)

什么是最好的方式来知道执行员服务何时已完成所有提交的任务

在 Flutter 中执行之前等待所有异步函数完成