在异步上下文中调用 subscribe 是否正确?

问题描述 投票:0回答:1

我将加密密钥存储在 Redis 数据库中。我想实现一个后备机制来生成密钥,除非它们已经存在。 让我困惑的是我提出的解决方案是在异步上下文中调用

subscribe
。我的 IDE 向我指出了这个问题。所以问题是你将如何实现这个后备?

public Mono<String> getEncryptionKey(String entity) {
    return reactiveRedisOperations.opsForValue()
            .get("private")
            .switchIfEmpty(
                    Mono.create(stringMonoSink -> {
                        try {
                            var privateKeyEncoded = ...
                            var publicKeyEncoded = ...

                            reactiveRedisOperations.opsForValue()
                                    .multiSet(Map.of(
                                            "private", privateKeyEncoded,
                                            "public", publicKeyEncoded
                                    ))
                                    .subscribe(success -> {
                                        stringMonoSink.success(privateKeyEncoded);
                                    });
                        } catch (Throwable e) {
                            stringMonoSink.error(e);
                        }
                    })
            );
}
java redis spring-webflux project-reactor
1个回答
1
投票

您可以使用

Mono.defer(Supplier<? extends Mono<? extends T>> supplier)
。它需要 Mono 的供应商,只有当 Mono 订阅时才会调用该供应商。在您的情况下,这意味着仅在
switchIfEmpty
:

的情况下才会调用密钥生成
    return reactiveRedisOperations.opsForValue()
            .get("private")
            .switchIfEmpty(Mono.defer(() -> {
                        var privateKeyEncoded = "...";
                        var publicKeyEncoded = "...";
                        return reactiveRedisOperations.opsForValue()
                                .multiSet(Map.of(
                                        "private", privateKeyEncoded,
                                        "public", publicKeyEncoded
                                ))
                                .map(b -> {
                                    if (b) return privateKeyEncoded;
                                    else throw new RuntimeException();
                                });
                    })
            );
© www.soinside.com 2019 - 2024. All rights reserved.