我有一个异步 API,它基本上通过分页返回结果
public CompletableFuture<Response> getNext(int startFrom);
每个Response对象包含一个偏移量列表startFrom和一个标志,指示是否还有更多元素剩余,因此,另一个getNext()请求。
我想编写一个遍历所有页面并检索所有偏移量的方法。我可以像这样以同步方式编写它
int startFrom = 0;
List<Integer> offsets = new ArrayList<>();
for (;;) {
CompletableFuture<Response> future = getNext(startFrom);
Response response = future.get(); // an exception stops everything
if (response.getOffsets().isEmpty()) {
break; // we're done
}
offsets.addAll(response.getOffsets());
if (!response.hasMore()) {
break; // we're done
}
startFrom = getLast(response.getOffsets());
}
换句话说,我们在 0 处调用getNext()with startFrom。如果抛出异常,我们将整个过程短路。否则,如果没有偏移,我们就完成了。如果有偏移量,我们将它们添加到主列表中。如果没有更多可取的,我们就完成了。否则,我们将 重置为startFrom我们获取并重复的最后一个偏移量。
理想情况下,我希望在不阻塞CompletableFuture::get()并返回CompletableFuture<List<Integer>>包含所有偏移量的情况下执行此操作。
我怎样才能做到这一点?我怎样才能组成期货来收集他们的结果?
我正在考虑“递归”(实际上不是在执行中,而是在代码中)
private CompletableFuture<List<Integer>> recur(int startFrom, List<Integer> offsets) {
CompletableFuture<Response> future = getNext(startFrom);
return future.thenCompose((response) -> {
if (response.getOffsets().isEmpty()) {
return CompletableFuture.completedFuture(offsets);
}
offsets.addAll(response.getOffsets());
if (!response.hasMore()) {
return CompletableFuture.completedFuture(offsets);
}
return recur(getLast(response.getOffsets()), offsets);
});
}
public CompletableFuture<List<Integer>> getAll() {
List<Integer> offsets = new ArrayList<>();
return recur(0, offsets);
}
从复杂性的角度来看,我不喜欢这个。我们能做得更好吗?
慕桂英3389331
慕森王
相关分类