【问题标题】:Mono::then returns nullMono::then 返回 null
【发布时间】:2020-02-13 20:22:20
【问题描述】:

我对响应式编程比较陌生。 我的问题是关于Mono::then

我想要做的是,从传入的请求中提取正文,将其设置为静态变量。 完成后,发送一个响应,说明服务已启动。 但是下面的代码总是返回“Service started for: null”。

我认为Mono::then 应该在第一个单声道完成后运行(在这种情况下,在设置静态变量之后)并返回“Service started for: a,b,c”。

我的理解有误吗?

(另外,任何代码批评都表示赞赏)

public Mono<ServerResponse> getStatus(ServerRequest req) {
        Mono<List<Request>> body = req.bodyToFlux(Request.class).collectList();
        return ServerResponse.ok()
                .body(body.doOnNext(i -> {
                    Service.a = i;
                    logger.info("Service started for : {}", i.toString());
                })


                        .then(Mono.just("Service started for: " + Service.a)), String.class);
    }

【问题讨论】:

  • "Mono::then 应该在后面运行" 没有什么可运行的。 Mono::just javadoc:“创建一个新的 Mono,它发出指定的项目,在实例化时被捕获。”你可以检查你对 Mono::then 的假设,使用 Mono::fromCallable, Mono::fromSupplier 而不是 Mono::just
  • 不应该 Mono::just 运行 "after" body.doOnNext 吗?

标签: java reactive-programming spring-webflux project-reactor


【解决方案1】:

非常不鼓励通过静态变量进行通信(尤其是在函数式和反应式编程中)。在您的问题中,您没有提供有关您开始的Service 的足够信息,因此有点难以推荐。

但是,根据现有信息,我会从以下内容开始:

public Mono<ServerResponse> getStatus(ServerRequest req) {
    return req.bodyToFlux(Request.class)
            .collectList()
            .doOnNext(requestBody -> System.out.println("Do your service start here in the background."))
            .flatMap(requestBody -> ServerResponse.ok().syncBody("Service started for: " + requestBody));
}

【讨论】:

  • 感谢马丁的回复。此后我进行了更改,不再使用静态变量。我想知道为什么Mono::then 没有按预期工作。我的理解是它应该等到之前的 Mono 结束,然后在 then() 中发出 mono。
  • 这是因为在执行流程的第一部分之前,内部的字符串正在被急切地评估,详细信息:stackoverflow.com/a/57877616/6051176 正如另一位评论者建议的那样,您可以使用 Mono::fromSupplier 来解决这个问题。
  • 这是因为在流程的第一部分执行之前,内部的字符串会被急切地评估是有意义的。谢谢你的解释。可以认为这是关闭的。
猜你喜欢
  • 2011-06-07
  • 1970-01-01
  • 2019-03-23
  • 2021-09-09
  • 1970-01-01
  • 2021-11-10
  • 2016-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多