【问题标题】:How to pass data down the reactive chain如何将数据向下传递到反应链
【发布时间】:2018-09-15 00:30:50
【问题描述】:

每当我需要将数据传递到反应链中时,我最终都会做这样的事情:

public Mono<String> doFooAndPassDtoAsMono(Dto dto) {
    return Mono.just(dto)
        .flatMap(dtoMono -> {
            Mono<String> result = // remote call returning a Mono
            return Mono.zip(Mono.just(dtoMono), result);
        })
        .flatMap(tup2 -> {
            return doSomething(tup2.getT1().getFoo(), tup2.getT2()); // do something that requires foo and result and returns a Mono
        });
}

给定以下示例 Dto 类:

class Dto {
    private String foo;

    public String getFoo() {
        return this.foo;
    }
}

因为一直压缩数据以将其向下传递(尤其是向下几级)通常会很乏味,所以我想知道是否可以像这样直接引用dto

public Mono<String> doFooAndReferenceParam(Dto dto) {
       Mono<String> result = // remote call returning a Mono
        return result.flatMap(result -> {
            return doSomething(dto.getFoo(), result); // do something that requires foo and result and returns a Mono
        });
}

我对第二种方法的担忧是,假设订阅者在线程池上订阅了这个 Mono,我需要保证 Dto 是线程安全的(上面的例子很简单,因为它只带有一个 String 但如果它是不是)?

另外,哪一个被认为是“最佳实践”?

【问题讨论】:

    标签: project-reactor


    【解决方案1】:

    根据您分享的内容,您可以简单地执行以下操作:

    public Mono<String> doFooAndPassDtoAsMono(Dto dto) {
        return Mono.just(dto.getFoo());
    }
    

    您在第一个选项中使用 zip 的方式并不能解决任何目的。同样,第二个选项也不起作用,因为一旦单声道为空,则不会触发下一个平面地图。

    【讨论】:

    • 我已将我的问题修改为更明确。 Mono 结果只是远程调用的任意单声道。
    • 在这种情况下,您的第二个选项很好。我假设您的 DTO 被创建为每个 db 命中的新对象。如果是,则不需要额外的线程安全。
    【解决方案2】:

    情况很简单,如果

    • 参考数据从一开始就可用(即在创建链之前),并且
    • 创建链最多可处理一个事件(即以 Mono 开头),并且
    • 参考数据是不可变的。

    然后您可以简单地引用参数或局部变量中的参考数据——就像在您的第二个解决方案中一样。这完全没问题,不存在并发问题。


    强烈建议不要在反应式流中使用可变数据。如果你有一个可变的 Dto 类,你可能仍然可以使用它(假设正确同步)——但这会让你的代码的读者非常惊讶。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多