【问题标题】:How to get a previously passed variable in reactor?如何在反应器中获取先前传递的变量?
【发布时间】:2019-03-12 06:34:07
【问题描述】:

我正在制作一个不和谐机器人作为构建在 project-reactor 之上的个人项目?

我需要调用一个函数,该函数需要获取一个在链上进一步传递的变量。

从下面的代码中,我需要传入两个参数。第一个需要来自 MessageCreateEvent 事件的参数,第二个需要来自 getContent 的参数。

我怎么能这样做,我是使用反应器的新手。

    discordClient.getEventDispatcher().on(MessageCreateEvent.class)
            .map(MessageCreateEvent::getMessage)
            .map(Message::getContent)
            .filter(Optional::isPresent)
            .map(o -> o.get())
            .map(this::getCommand)
            .filter(Objects::nonNull)
            .map(msg -> msg.runCommand(null, null))
            .subscribe();

我也试过这个,但我没有看到 runCommand() 被调用。:

    discordClient.getEventDispatcher().on(MessageCreateEvent.class)
            .flatMap(event ->
                Mono.just(event)
                .map(MessageCreateEvent::getMessage)
                .map(Message::getContent)
                .filter(Optional::isPresent)
                .map(o -> o.get())
                .map(this::getCommand)
                .filter(Objects::nonNull)
                .map(msg -> msg.runCommand(event, null))
            )
            .subscribe();

【问题讨论】:

  • 你不能。您需要使用带有flatMap 的嵌套通量或传递元组。我个人更喜欢前一种解决方案。
  • 你是如何制作它们的?我以为它只是在事件之后添加一个flatMap,然后添加一个(事件-> on() 之后的其余代码),但是没有调用runCommand。
  • 你没有doOnError,也没有doOnNext。你只需调用subscribe() 并将结果放在地板上 - 你怎么知道什么叫什么不叫?
  • 我想到了两种可能性:您在 test/main 中执行此操作,并且线程在序列有机会运行(异步)之前退出,或者消息被过滤掉(无内容/空命令)。如下所示,您可以使用log() 更好地了解在哪个步骤会发生什么。

标签: java project-reactor reactor


【解决方案1】:

flatMap 很好。该错误可能与您预期的不同。这可能会帮助您弄清楚发生了什么(假设您有一个名为“log”的可用记录器对象):

Mono.just(event)
    .doOnNext(log::info)
    .map(MessageCreateEvent::getMessage)
    .doOnNext(log::info)

等你的流的每一行。在最后一行你可能想添加:

.doOnEach(s -> log.info("signal: " + s)))

仅供参考,或者对于其他偶然发现这一点的人,从技术上讲, 有一种方法可以使用在链上传递的东西,zipWhen():

discordClient
    .getEventDispatcher()
    .on(MessageCreateEvent.class)
    .zipWhen(
        event ->
            Mono.just(event)
                .map(MessageCreateEvent::getMessage)
                .map(Message::getContent)
                .filter(Optional::isPresent)
                .map(o -> o.get())
                .map(this::getCommand)
                .filter(Objects::nonNull),
        (event, msg) -> msg.runCommand(event, null))
    .subscribe();

但这不会让你的代码更干净!但对于某些其他情况,它可能会很方便。

【讨论】:

  • 还有 .log() 内置运算符用于记录到达特定步骤的所有事件。将使用 slf4j、jdk 日志记录,甚至默认使用控制台。
  • @SimonBaslé 是的。使用 doOnNext 手动执行此操作的好处是您可以看到值的进度并通过您的流进行转换。你也可以在每一步都使用 .log(),但是你会重复看到所有的信号。
猜你喜欢
  • 2022-01-19
  • 1970-01-01
  • 2018-08-20
  • 1970-01-01
  • 1970-01-01
  • 2020-06-04
  • 2017-03-01
  • 1970-01-01
  • 2021-05-27
相关资源
最近更新 更多