Я сравнительно не знаком с реактивными 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 из контроллера?