如何迭代 Flux 并使用另一个 Mono 的结果来过滤 Flux

akr*_*.21 3 java project-reactor reactive spring-webflux

Mono<MyObj1> mono1 = repository.get(id); // data from reactive mongo
Flux<MyObj2> availabilityInfo = getAvailabilityInfo(); // blocking I/O call
Run Code Online (Sandbox Code Playgroud)

我想要实现的是迭代 availabilityInfo 并需要使用单声道数据应用一些条件并返回 MyObj2(其中包含该日期的 delieveryDate 和价格相关信息)。

我将尝试用幼稚的编码解释如下

 foreach(MyObj2 obj : availabilityInfo){
      if(MyObj1.getX() && obj.getY()){
         return or break;
      }
  }
Run Code Online (Sandbox Code Playgroud)

我想从满足标准的通量中发出第一个元素 - MyObj1.getX() && obj.getY(),即使通量中还有其他元素符合标准。该标准基于来自 mono 的响应,这是一个反应性 mongo db 调用和来自发射通量元素的少数事实。

une*_*q95 5

方式一:

 Mono<MyObj2> filteredInfo = mono1.flatMapMany(myObj1 -> 
                                        availabilityInfo.filter(myObj1 -> myObj1.getX() && myObj2.getY()).take(1)).single();
Run Code Online (Sandbox Code Playgroud)

方式二:

Mono<MyObj2> filteredInfo  = availabilityInfo.collectList().zipWith(mono1).flatMap(tuple -> {
            List<MyObj2> list = tuple.getT1();
            MyObj1 myObj1 = tuple.getT2();
            for(MyObj2 myObj2:list){
                if(myObj1.getX() && myObj2.getY()){
                    return Mono.just(myObj2);
                }
            }
            return Mono.empty();
        });
Run Code Online (Sandbox Code Playgroud)

flatMapMany用于通过处理单声道来创建通量。filter采用一个谓词,它构成了过滤流量的基础。

例子:

 Mono<Integer> mono = Mono.just(3);
        Flux<Integer> flux = Flux.just(1, 2, 3, 4, 5, 6);
        //Way 1
        Mono<Integer> res = mono.flatMapMany(i -> flux.filter(j -> j % i == 0).take(1)).single();

        res.subscribe(System.out::println);

        //Way 2
       flux.collectList().zipWith(mono).flatMap(tuple -> {
        List<Integer> list = tuple.getT1();
        int x = tuple.getT2();
        for(int y:list){
            if(y%x==0){
                return Mono.just(x);
            }
        }
        return Mono.empty();
    }).subscribe(System.out::println);
Run Code Online (Sandbox Code Playgroud)

两种方式都会给我输出:

3
Run Code Online (Sandbox Code Playgroud)