如何从返回 Mono 的 Stream 创建 Flux? [复制]

Posted

技术标签:

【中文标题】如何从返回 Mono 的 Stream 创建 Flux? [复制]【英文标题】:How to create Flux from a Stream that returns Mono? [duplicate] 【发布时间】: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 替换为等效(或更好)的代码。

【问题讨论】:

【参考方案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()));

以上是关于如何从返回 Mono 的 Stream 创建 Flux? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何使用返回 Mono 的生成包装调用创建 Flux

如何以响应式方式通过 Mono 返回应用程序/pdf

如何从 Spring Flux 平面图操作中返回对象

Reactive Stream: 如何将两个数据流接到一起,然后进行操作

从 Mono 的列表中创建 Flux 的正确方法

如果 Mono 为空,则创建未找到的 ServerResponse