【问题标题】:How to create Flux from a Stream that returns Mono? [duplicate]如何从返回 Mono 的 Stream 创建 Flux? [复制]
【发布时间】:2020-11-19 05:34:33
【问题描述】:

假设我有一个带有 (CourseID, Name) 的课程名称对象列表。让我们将该列表称为“courseNameList”。

当有人向“/courses”发送请求时,我们希望显示课程列表。

但是,在发送结果之前,我还需要附加每门课程的价格。价格将从另一个微服务中检索,并返回一个 Mono 对象。

因此,用户将看到带有(ID、名称、价格)的课程列表。价格来自其他服务。

控制器方法可能如下所示

@GetMapping("/courses")
public Flux<Course> gerProducts() {
 courseNameList.stream.map(courseName -> {
      //Make a webClient call to pricing service by sending coureName.getID as parameter and get the 'price' Mono object
      //return the course object with id, name, price
   })
     //Collect and return Flux with contains list of courses!
}

我尝试了多种方法来返回 Flux。但是,我无法弄清楚如何。我需要将这些 cmets 替换为等效(或更好)的代码。

【问题讨论】:

    标签: java spring-boot reactive-programming spring-webflux


    【解决方案1】:

    从通量而不是列表开始会更好,但如果不可能,则从如下流中创建通量,然后使用 flatMap 而不是 map。

    @GetMapping("/courses")
    public Flux<Course> gerProducts() {
      return Flux.fromStream(courseNameList.stream()).flatMap(courseName -> {
        // Make webClient call which returns mono
      });
    }
    

    【讨论】:

      【解决方案2】:

      你可以看看这个例子,自己想出一个解决方案。

      // I assumed you have courses list already as you are using a list.
       List<String> list = List.of("a", "bb", "ccccc", "ddd");
       Flux.fromIterable(list)
             // this is where you find the price and append
             .flatMap(a -> Mono.just(a).map(k -> k + ":" + k.length()))                 
             .subscribe(System.out::println);
      
      //output
      a:1
      bb:2
      ccccc:5
      ddd:3
      

      但是,如果您有 100 门课程,您是否愿意一一调用该服务 100 次。不会影响性能吗?相反,您可以发送课程列表并通过 1 个电话从服务中获取价格吗?

      // you have courses list
      List<String> list = List.of("a", "bb", "ccccc", "ddd");
      
      // get the price of all courses in 1 call
      Mono.fromSupplier(() -> List.of(1, 2, 5, 3))
              .flatMapIterable(Function.identity())
              .index()
              // map the courses and price
              // I used index. but you could use courseID to map the price
              .map(t -> list.get(t.getT1().intValue()) + ":" + t.getT2())
              .subscribe(System.out::println);
      

      【讨论】:

      • 以下代码返回 null。请注意,“getCourseMonoObject”方法将根据 ID 给出“Course”的 Mono 对象,而 courseIDList 只是课程 ID 的列表。 //代码开始 @GetMapping("/course/list") public Flux gerProducts() { return Flux.fromIterable(courseIDList) .flatMap(coursename -> getCourseMonoObject(coursename.getCourseID())); }
      猜你喜欢
      • 1970-01-01
      • 2020-08-28
      • 2022-01-09
      • 1970-01-01
      • 2020-10-28
      • 2020-01-02
      • 2018-11-20
      • 1970-01-01
      • 2021-08-02
      相关资源
      最近更新 更多