【问题标题】:How to use return object of Mono without using block()?如何在不使用 block() 的情况下使用 Mono 的返回对象?
【发布时间】:2020-08-04 01:08:29
【问题描述】:

我正在尝试学习 spring webflux。在ReactiveMongoRepository 中,我正在尝试检查类别是否已经存在。如果它已经存在,则返回该对象,否则保存并返回新保存的对象。类似于以下内容。

public Mono<Category> save(Category category) {
    final Mono<Category> byId = repository.findById(category.getId());
    final Category block = byId.block();
    if (block == null) {
        return repository.save(new Category(category.getName()));
    } else {
        return byId;
    }
}

如果不使用block(),我该如何做到这一点?

【问题讨论】:

  • 使用switchIfEmtpy 而不是block

标签: java spring spring-boot spring-webflux project-reactor


【解决方案1】:

使用Mono::switchIfEmpty 提供替代Mono,以防前者在没有数据的情况下完成。只要ReactiveMongoRepository::save返回Mono,就可以通过它来生成替代。

return repository.findById(category.getId())
                 .switchIfEmpty(repository.save(new Category(category.getName())));

如果ReactiveMongoRepository::findById 返回带有数据的Mono,则不会调用Mono::switchIfEmpty

编辑:Mono::deferSupplier&lt;Mono&gt; 一起使用会使保存操作在必要时延迟:

.switchIfEmpty(Mono.defer(() -> repository.save(new Category(category.getName()))));

【讨论】:

  • 这并不完全正确。 respository.save 将被急切地调用。
  • 是的。调用save 方法后立即返回带有结果的Mono,使用Mono::defer 应该会有所帮助。问题是关于使用避免block() 操作。然而,一个好点!
【解决方案2】:

你可以试试这样的

public Mono<Category> getCategories(Category category) {
   return repository.findByName(category.getName()).doOnNext(o -> {
   }).switchIfEmpty(repository.save(category));
}

【讨论】:

    【解决方案3】:

    您需要推迟switchIfEmpty。否则,它会被急切地触发:

    return repository.findById(category.getId())
                     .switchIfEmpty(Mono.defer(() ->respository.save(category)));
    

    【讨论】:

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