最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

spring webflux - Why is switchIfEmpty not being executed? - Stack Overflow

programmeradmin4浏览0评论

In the below code logic switchIfEmpty is not getting executed. As per below code logic I am expecting lowerCase names when filter(__ -> names.size() > 5) evaluates to false and upperCase names when filter(__ -> names.size() > 3) evaluates to true. It is working as expected if filter evaluates true but it is not working when filter evaluates to false. Why is that?

List<String> names = Arrays.asList("google", "abc", "fb", "stackoverflow");

Flux.fromIterable(names)
                .filter(name -> name.length() > 5)
                .collectList()
                .flatMap(commonAppliedFilters -> Mono.just(commonAppliedFilters)
                    .filter(__ -> names.size() > 5)
                    .flatMapIterable(list -> list)
                    .map(String::toUpperCase)
                    .collectList()
                    .switchIfEmpty(Mono.defer(() -> Mono.just(commonAppliedFilters))))
                .subscribe(System.out::println);

In the below code logic switchIfEmpty is not getting executed. As per below code logic I am expecting lowerCase names when filter(__ -> names.size() > 5) evaluates to false and upperCase names when filter(__ -> names.size() > 3) evaluates to true. It is working as expected if filter evaluates true but it is not working when filter evaluates to false. Why is that?

List<String> names = Arrays.asList("google", "abc", "fb", "stackoverflow");

Flux.fromIterable(names)
                .filter(name -> name.length() > 5)
                .collectList()
                .flatMap(commonAppliedFilters -> Mono.just(commonAppliedFilters)
                    .filter(__ -> names.size() > 5)
                    .flatMapIterable(list -> list)
                    .map(String::toUpperCase)
                    .collectList()
                    .switchIfEmpty(Mono.defer(() -> Mono.just(commonAppliedFilters))))
                .subscribe(System.out::println);
Share Improve this question edited Mar 24 at 18:58 Doug Breaux 5,1051 gold badge27 silver badges68 bronze badges asked Mar 19 at 11:10 SuhailSuhail 11 bronze badge
Add a comment  | 

1 Answer 1

Reset to default 0

What happened is that the collectList returned a Mono with an empty list, but not a Mono.empty, so we have:

...
.collectList()
.filter(list -> !list.isEmpty())

or

...
.collectList()
.flatMap(list -> !list.isEmpty() ? Mono.just(list) : Mono.empty())

With this we successfully force a Mono.empty() that will trigger your switchIfEmpty().

I show you an example testing with StepVerifier.

<dependency>
    <groupId>io.projectreactor</groupId>
    <artifactId>reactor-test</artifactId>
    <scope>test</scope>
    <version>3.7.0</version>
</dependency>

You can decomment the flatMap to see how it works as well.

class ReactiveTest {

    @Test
    @DisplayName("expecting lowerCase names when filter(__ -> names.size() > 5)")
    void expectingLowerCase() {
        List<String> names = Arrays.asList("google", "abc", "fb", "stackoverflow");

        StepVerifier.create(Flux.fromIterable(names)
                        .filter(name -> name.length() > 5)
                        .collectList()
                        .flatMap(commonAppliedFilters ->
                                Mono.just(commonAppliedFilters)
                                        .filter(__ -> names.size() > 5)
                                        .flatMapIterable(list -> list)
                                        .map(String::toUpperCase)
                                        .collectList()
                                        //.flatMap(list -> !list.isEmpty() ? Mono.just(list) : Mono.empty())
                                        .filter(list -> !list.isEmpty())
                                        // If the list is empty, a Mono.empty() is returned which will force switchIfEmpty
                                        .switchIfEmpty(Mono.defer(() -> Mono.just(commonAppliedFilters)))
                        ))
                .expectNext(List.of("google", "stackoverflow"))
                .verifyComplete();
    }

    @Test
    @DisplayName("expecting upperCase names when filter(__ -> names.size() > 3) ")
    void expectingUpperCase() {
        List<String> names = Arrays.asList("google", "abc", "fb", "stackoverflow");

        StepVerifier.create(Flux.fromIterable(names)
                        .filter(name -> name.length() > 5)
                        .collectList()
                        .flatMap(commonAppliedFilters ->
                                Mono.just(commonAppliedFilters)
                                        .filter(__ -> names.size() > 3)
                                        .flatMapIterable(list -> list)
                                        .map(String::toUpperCase)
                                        .collectList()
//                                        .flatMap(list -> !list.isEmpty() ? Mono.just(list) : Mono.empty())
                                        .filter(list -> !list.isEmpty())
                                        .switchIfEmpty(Mono.defer(() -> Mono.just(commonAppliedFilters)))
                        ))
                .expectNext(List.of("GOOGLE", "STACKOVERFLOW"))
                .verifyComplete();
    }

}

发布评论

评论列表(0)

  1. 暂无评论