Что происходит, когда поток возвращается из пружинного веб-контроллера? - PullRequest
2 голосов
/ 26 марта 2019

Я сравнительно не знаком с реактивными API и мне было интересно узнать, что происходило за кулисами, когда мы возвращаем Flux с веб-контроллера.

Согласно весенне-веб-документации

Реактивные возвращаемые значения обрабатываются следующим образом:

Адаптировано однозначное обещание, аналогичное использованию DeferredResult. Примеры включают Mono (Reactor) или Single (RxJava).

Адаптированный к нескольким значениям поток с типом потокового мультимедиа (таким как application / stream + json или text / event-stream) адаптирован к аналогично использованию ResponseBodyEmitter или SseEmitter. Примеры включают Flux (Reactor) или Observable (RxJava). Приложения также могут возвращать Flux или Observable.

Многозначный поток с любым другим типом мультимедиа (например, application / json) адаптирован, аналогично использованию DeferredResult<List<?>>.

Я создал два API, как показано ниже:

@GetMapping("/async-deferredresult")
public DeferredResult<List<String>> handleReqDefResult(Model model) {
    LOGGER.info("Received async-deferredresult request");
    DeferredResult<List<String>> output = new DeferredResult<>();

    ForkJoinPool.commonPool().submit(() -> {
        LOGGER.info("Processing in separate thread");
        List<String> list = new ArrayList<>();
        for (int i = 0; i < 10000   ; i++) {
            list.add(String.valueOf(i));
        }
        output.setResult(list);
    });

    LOGGER.info("servlet thread freed");
    return output;
}


@GetMapping(value = "/async-flux",produces = MediaType.APPLICATION_JSON_VALUE)
public Flux<String> handleReqDefResult1(Model model) {
    LOGGER.info("Received async-deferredresult request");
    List<String> list = new ArrayList<>();
    list.stream();
    for (int i = 0; i < 10000   ; i++) {
        list.add(String.valueOf(i));
    }
    return Flux.fromIterable(list);
}

Таким образом, исключение состояло в том, что оба API должны вести себя так же, как поток с несколькими значениями (Flux) должен иметь поведение, аналогичное возвращению DeferredResult.
Но в API, где был возвращен отложенный результат, весь список был напечатан за один раз в браузере, как в API, где Flux возвращал числа, которые печатались последовательно (по одному).
Что именно происходит, когда я возвращаю Flux из контроллера?

...