代码之家  ›  专栏  ›  技术社区  ›  Miguel Gamboa

将CompletableFuture转换为Publisher是否正确?

  •  25
  • Miguel Gamboa  · 技术社区  · 7 年前

    允许对来自 CompletableFuture<Stream<String>> 我正在考虑以下方法之一:

    1. 将生成的未来转换为 CompletableFuture<List<String>> 通过: teams.thenApply(st -> st.collect(toList()))

    2. 将生成的未来转换为 Flux<String> 使用缓存: Flux.fromStream(teams::join).cache();

    Flux<T> 是否实施 Publisher<T> 项目内反应堆。

    用例:

    我想获得英超球队名称的序列(例如。 Stream<String> )从提供 League 具有 Standing[] (基于足球数据RESTful API,例如。 http://api.football-data.org/v1/soccerseasons/445/leagueTable )。使用 AsyncHttpClient Gson 我们有:

    CompletableFuture<Stream<String>> teams = asyncHttpClient
        .prepareGet("http://api.football-data.org/v1/soccerseasons/445/leagueTable")
        .execute()
        .toCompletableFuture()
        .thenApply(Response::getResponseBody)
        .thenApply(body -> gson.fromJson(body, League.class));
        .thenApply(l -> stream(l.standings).map(s -> s.teamName));
    

    要重用生成的流,我有两个选项:

    1. CompletableFuture<List<String>> res = teams.thenApply(st -> st.collect(toList()))
    
    2. Flux<String> res = Flux.fromStream(teams::join).cache()
    

    通量(&L);T> 没有那么冗长,提供了我所需要的一切。然而,在这种情况下使用它是否正确?

    或者我应该使用 可完成的未来<列表(<);字符串(>)&燃气轮机; 相反或者还有其他更好的选择吗?

    更新了一些想法(2018-03-16) :

    可完成的未来<列表(<);字符串(>)&燃气轮机; :

    • 【专业人士】The List<String> 将继续收集,当我们需要继续处理未来的结果时,可能已经完成。
    • [反对]声明冗长。
    • [缺点]如果我们只想使用一次,那么我们不需要在 List<T>

    通量(&L);字符串(>); :

    • [优点]声明简洁
    • [优点]如果我们只想使用一次,那么我们可以省略 .cache() 并将其转发到下一层,该层可以利用反应式API,例如web流量反应式控制器,例如。 @GetMapping(produces =MediaType.TEXT_EVENT_STREAM) public Flux<String> getTeams() {…}
    • 如果我们想重复使用 通量(&L);T> 我们必须用可缓存的 通量(&L);T> ( ….cache() )这反过来会增加第一次遍历的开销,因为它必须将结果项存储在内部缓存中。
    2 回复  |  直到 5 年前
        1
  •  15
  •   youhans    2 年前
        CompletableFuture<Stream<String>> teams = ...;
        Flux<String> teamsFlux = Mono.fromFuture(teams).flatMapMany(stream -> Flux.fromStream(stream));
    

    Flux.fromStream(teams::join) 是一种代码气味,因为它阻止当前线程从 CompletableFuture 正在另一个线程上运行。

        2
  •  4
  •   Stéphane Appercel    7 年前

    一旦下载了联赛表,并从此表中提取了球队名称,我不确定您是否需要背压就绪流来迭代这些项目。流到标准列表(或数组)的转换应该足够好,并且可能有更好的性能,不是吗?

    例如:

    String[] teamNames = teams.join().toArray(String[]::new);