当前位置: 首页 > 知识库问答 >
问题:

当flux从spring web Controller返回时会发生什么?

常智勇
2023-03-14

我对反应性API比较陌生,很好奇当我们从web控制器返回流量时,幕后发生了什么。

根据spring-web文档

反应性返回值的处理如下:

与使用DeferreDreSult类似,适用于单值promise。例子包括单(反应器)或单(RxJava)。

@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中,流量被返回顺序打印的数字(一个接一个)。
当我从控制器返回流量时,到底发生了什么?

共有1个答案

邵伟泽
2023-03-14

当我们从服务endpoint返回流量时,可能会发生许多事情。但是我假设您想知道当从这个endpoint的客户端观察到Flux作为事件流时会发生什么。

场景一:通过添加'application/JSON'作为endpoint的内容类型,Spring将与客户机通信以期待JSON主体。

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

因此,您看不到反应性API的真正价值。

@GetMapping(value = "/async-flux",produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
public Flux<String> handleReqDefResult1(Model model) {
    List<String> list = new ArrayList<>();
    for (int i = 0; i < 10000   ; i++) {
        list.add(String.valueOf(i));
    }
    return Flux.fromIterable(list)
            // we have 1 sec delay to demonstrate the difference of behaviour. 
            .delayElements(Duration.ofSeconds(1));
}

这一次,我们可以看到reactive api endpoint的真正价值,在那里,当数据可用时,它能够将结果交付给它的客户机。

您可以在https://medium.com/@senanayake.kalpa/building-reactive-rest-apis-in-java-part-1-CD2C34AF55C6 https://medium.com/@senanayake.kalpa/building-reactive-rest-apis-in-java-part-2-BD270D4CDF3F找到关于如何构建反应性REST API的更多细节

 类似资料:
  • 问题内容: 有人可以提供goroutine返回的澄清值。从goroutine返回的值是否已存入抵押。 例如: 我们是否应该避免在go例程中避免返回值? 问题答案: 快速查看一下组装输出显示 该函数确实将其结果存储到堆栈中 因此,当从goroutine调用它时,它会将结果存储到堆栈中。但是,这是一个新的堆栈,当goroutine结束时,该堆栈会被破坏,因此无法获取返回值。 但是,无法检索这些结果。

  • 问题内容: 用伪代码更好地解释自己。我目前正在学习Java。 如果我有方法 我不能,rs.close()因为我需要在检索它的方法中使用它,因此我将使用它,并且可能“关闭”我创建的新resultSet。 与先前的resultSet会发生什么?是否留给垃圾收集器收集?当我关闭“新” resultSet时,它会自行关闭吗?对代码效率/性能有影响吗? 任何反馈将不胜感激:),因为这让我有些困惑。我认为这更

  • 在 C 中,当一个应该返回对象的函数在没有 return 语句的情况下结束时会发生什么?会得到什么回报? 例如。

  • 谁能给我解释一下,当我改变从find函数返回的值时,为什么原始数组中的值会改变呢?是不是有一个我缺失的概念?在执行代码之后,我将得到下面提到的输出。

  • 我在yarn cluster上运行的spark应用程序崩溃了,我正在试图确定根本原因。在我使用从yarn获得的日志中,我看到在块获取期间有一大堆连接被拒绝,还有一个内存不足错误。很难说出根本原因是什么。我的问题是当容器因为OutOfMemory异常而被杀死时会发生什么。因此,在容器日志中,我看到这是如何在容器上启动执行器的 我还看到许多。在应用程序崩溃之前,似乎有多个这样的问题。spark重试一个

  • 我做了研究,发现应该这样做我不知道java对象像指针一样工作。我以为只有当两个对象相等时才会传递值。我甚至创建了一个简单的测试应用程序,它可以设置和获取一个对象的数量。再一次,我把这两个对象都等同起来。更改一个对象的元素似乎也会影响另一个对象。我不知道该怎么在谷歌上搜索这个。所以我才把整个故事都告诉你。我只得到与c编程有关的文档。我觉得我的底子都碎了。我现在才知道是如何工作的。我试着做 这不影响N