在不再次触发可观测序列的情况下重新订阅Mono

后端开发 2026-07-11

我有一个处理流程会接收一个数据项,并可能需要该数据项在外部服务中存储的某个属性。由于获取这个属性耗时,我想在收到数据项时就对该属性进行查询。

public class Item(){
    public Item(String id, Map<String, Object> bunchOfThings){
        this.id = id;
        this.things = bunchOfThings;
        externalService.methodThatReturnsMono(id)
            .subscribe(attribute -> this.attribute = Optional.of(attribute));
    }


    Optional<String> attribute = Optional.empty();
}

如果确实需要这个属性,理想情况下这个值已经获取到了。但是如果没有对外部服务进行调用,会怎么样?

public String getAttribute() {
    if(attribute.isPresent())
        return attribute.get();
    else
        //I want to wait until the attribute is obtained, like get hooked again in the reactive flow and wait till is done, not resubscribe and trigger again the "methodThatReturnsMono"
}

在开始对该可选项进行循环轮询之前,我想知道是否存在一种响应式的实现方式,还是说我是在把圆钉塞进方孔里。

解决方案

你可以使用 Mono.cache(),而不是将其存储为Optional(可选值)对象。使用缓存的Mono,第一次对它进行订阅时(可能是提前订阅,比如在你的第一段代码中),它会触发计算,随后再次订阅时只从缓存中获取已经计算的值。

这样可以保持线程安全,并维持响应式API的暴露,同时避免在每次访问时重新触发计算。

我们可以将你的示例改成这样:

public class Item {

    private final Mono<String> attribute;

    public Item(String id, Map<String, Object> bunchOfThings){
        this.id = id;
        this.things = bunchOfThings;
        attribute = externalService.methodThatReturnsMono(id)
                                   .cache();
        // prefetch attribute value
        attribute.subscribe();
    }


    public Mono<String> getAttribute() { return attribute; }
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章