代码之家  ›  专栏  ›  技术社区  ›  billydh

Reactor-如果未通过过滤器,如何在使用过滤器的同时仍通过该值进行日志记录?

  •  0
  • billydh  · 技术社区  · 5 年前

    我正在努力找出正确的方法来做下面的事情。

    • 我想通过检查数据库中是否存在记录 name ,这是一个全球二级指数。(假设主键是 id ).
    • 如果已经有一个项目 名称 ,然后记录 身份证件 名称 并返回一个错误。
    • 如果没有具有给定 名称 ,然后继续。

    现在,代码结构是这样的。

    private fun checkExistingData(name: String): Mono<QueryResponse> {
      return repo.getDataByName(name)
        .filterWhen { Mono.just(!it.hasItems()) }
        .switchIfEmpty {
          // log the existing id and name from QueryResponse
          Mono.error(SomeCustomException))
        }
        .flatMap {
          // proceed
        }
    }
    

    如你所见,如果我想记录 身份证件 switchIfEmpty 条款,我需要这样做 repo.getDataByName(name) 在它中,可以检索项目并获取 身份证件 这个项目的一部分。显然,这是低效的,因为我之前已经这么做了 切换为空 .

    正确的方法是什么?

    0 回复  |  直到 5 年前
        1
  •  1
  •   Simon Baslé    5 年前

    等待更多关于 QueryResponse API,我将假设一些事情: - getDataByName 返回一个 Mono<QueryResponse> Mono 总是很值钱的(它总是正好发出一声) QueryResponse 是否能找到数据 - QueryResponse#items 在我的示例中,我将使用它来访问正确的行。我还要假设它返回一个 Flux<Item>

    首先, filterWhen 因为我们还有一个 filter(boolean) 方法我认为反向过滤逻辑可能更难理解。

    为什么不把家里的一切都做好呢 flatMap 相反

    private fun checkExistingData(name: String): Mono<QueryResponse> {
      return repo.getDataByName(name)
        .flatMap {
           if (it.hasItems())
             it.items()
               .single()
               .doOnNext(existing -> logExisting(existing.id(), existing.name())
               .then(Mono.error(SomeCustomException)
            else
              proceed()
        }   
    }
    
        2
  •  1
  •   Erik Finnman    4 年前

    如果你第一次打电话给 repo.getDataByName 返回一个 Mono 还有这个 单声道 如果为空,则不需要对该情况进行筛选,因为不会调用管道的其余部分。所以我认为你可以保留 switchIfEmpty() 记录这个特殊的案例,然后继续 flatMap() :

    private fun checkExistingData(name: String): Mono<QueryResponse> {
      return repo.getDataByName(name)
        .switchIfEmpty {
          // log the existing id and name from QueryResponse
          Mono.error(SomeCustomException))
        }
        .flatMap {
          // proceed
        }
    }