Мой весенний webflux flatMap, doOnNext, doFinally не вызывается для внутреннего Mono? - PullRequest
0 голосов
/ 26 мая 2019

Я абсолютно новичок в реакторе. Моя flatMap, doOnNext, doFinally не вызывается для внутреннего Mono. Я добавил пример теста и его вывод, в котором описана проблема. Он не будет вызван, даже если я поменяю getMeIntegerMono2 на getMeStringMono, я что-то не так делаю?

@Test
    public void prodBug() {
        System.out.println(Final());
    }

    String Final(){
        final String[] val = new String[1];
        System.out.println("1 - "+Thread.currentThread().getName());

        Mono<Integer> intMono =
                getMeIntegerMono("2")
                        .doOnNext(integer -> {
                            getMeIntegerMono2("21")
                                    .flatMap(s -> getMeStringMono(String.valueOf(s)));
                        });

        System.out.println("2 - "+Thread.currentThread().getName());

        intMono.subscribe(integer -> {
            val[0] =String.valueOf(integer);
        });
        System.out.println("3 - "+Thread.currentThread().getName());
        return val[0];
    }

    Mono<String> getMeStringMono(String val){
        System.out.println("String Mono - "+Thread.currentThread().getName());
        return Mono.just(val);
    }


    Mono<Integer> getMeIntegerMono(String val){
        System.out.println("Integer Mono - "+Thread.currentThread().getName());
        return Mono.just(Integer.parseInt(val));
    }

    Mono<Integer> getMeIntegerMono2(String val){
        System.out.println("Integer Mono2 - "+Thread.currentThread().getName());
        return Mono.just(Integer.parseInt(val));
    }

вывод

1 - main
Integer Mono - main
2 - main
Integer Mono2 - main
3 - main
2

Процесс завершен с кодом выхода 0

1 Ответ

1 голос
/ 26 мая 2019

Есть несколько проблем с вашим кодом.

В Reactor, ничего не происходит, пока вы не подпишетесь .То есть простое создание Mono ничего не делает .В функции, которую вы передаете doOnNext, вы создаете Mono, на который никогда не подписывается.Поэтому функция, которую вы передаете flatMap, никогда не будет вызвана.Попробуйте использовать flatMap вместо doOnNext (вам понадобится немного поиграть с типами, чтобы заставить его работать).

Одна из проблем при тестировании связана с разница между «временем сборки» и «временем выполнения».Во всех ваших getMe* методах вы сразу что-то печатаете, а затем возвращаете Mono.Это на самом деле вводит в заблуждение при отладке, потому что печать будет происходить во время сборки, даже если возвращенный Mono никогда не выполняется.Вы можете выполнять побочные эффекты во время выполнения, вместо этого используя Mono.defer() или Mono.fromSupplier().

Техника использования массива для обхода ограничений Java на переменные и лямбда-выражения является плохой практикой, и хотя она может работать в этомслучай, вы должны выйти из привычки, так как он очень хрупкий.Чтобы понять почему, представьте, что какой-то Mono в вашей цепочке выполняет дорогостоящую операцию в другом потоке.Это означает, что функция, которую вы передаете subscribe, будет вызываться после того, как Final() уже вернется.

...