Почему итерируемый поток не работает в Spring Boot Controller для данных из mongodb? - PullRequest
0 голосов
/ 13 сентября 2018

У меня есть весеннее реактивное веб-приложение, использующее реактивный драйвер монго для mongodb в типичном таком приложении.

Ниже приведен код в контроллере:

Flux<Foo> foos = fooService.findAllFoos();

Flux<Integer> squared = Flux.range(1, 10).map(x -> x * x);

Iterable<Integer> iter = squared.toIterable();
for (Integer i : iter) {
    log.info("square int is: " + i);
} 

Iterable<Foo> iter2 = foos.toIterable();
for (Foo foo : iter2) {
    log.info("ID is: " + foo.getId());
} 

int tm = 3;

iter работает и печатает значения, но iter2 ничего не печатает, даже если foos не пуст.Почему?

foos происходит от:

import org.springframework.data.repository.reactive.ReactiveCrudRepository;

public interface FooRepository extends ReactiveCrudRepository<Foo, String> {    

    Flux<Foo> findAll();
}

Также он зависает, браузер продолжает ждать запроса, и последняя строка кода (int tm = 3) не выполняется.Почему?

Ответы [ 2 ]

0 голосов
/ 15 сентября 2018

Ваш вопрос действителен. Здесь есть только 1 объяснение:

iterator.next () является блокирующим вызовом. А поскольку ваш поток кода заблокирован, это означает, что итератор еще не готов. Это может произойти, если fooService.findAllFoos () возвращает огромный список и требует времени.

Можете ли вы сказать, сколько записей будет возвращено функцией fooService.findAllFoos ()?

Или попробуйте удалить некоторые записи и, скажем, оставить только несколько, скажем, 2 0r 3 записей, а затем посмотреть. Я считаю, что это должно сработать.

Итератор не будет готов, пока не поступит сигнал complete от Flux.
Пожалуйста, проверьте и дайте мне знать.

0 голосов
/ 13 сентября 2018

ваш поток не последовательный, поэтому попробуйте с ниже

    Flux<Foo> foos = fooService.findAll();
    return foos.flatMap(foo-> {
       //do something with foo
        return foo;

    }).switchIfEmpty(Flux.defer(() -> {
       //handle empty case.
        Iterable<Integer> iter = squared.toIterable();
        for (Integer i : iter) {
            log.info("square int is: " + i);
        }
        return 3;
    }));

ОБНОВЛЕНИЕ

Чтобы ответить на ваш вопрос:

toIterable () блокируетпоток, поэтому он не будет выполнять следующие операторы. поэтому используйте flatmap в Mono или Flux.

...