在哪里使用Mono/Flux?

Where to use Mono/Flux?

我有点被迫转向使用 WebFlux 的反应式编程(并且在很短的时间内),我真的很难理解它。也许是因为缺少示例,或者是因为我从未做过函数式编程。

无论如何,我的问题是在哪里使用 Mono/Flux 以及在哪里可以使用普通对象?例如。我的控制器正在等待一个@Valid User 对象,它应该是@Valid Mono 还是类似Mono<@Valid User> 的对象?如果假设它只是一个 User 对象,我将它传递到我的服务层,我想在将密码保存到响应式 MongoDb 之前对密码进行编码,我应该写:

User.setPassword(...);
return reactiveMongoDbRepository.save(user); //returns Mono<User> which is returned by the Controller to the View

或者应该是这样的

return Mono.just(user).map.flatmap(setPasswordSomewhereInThisHardToFollowChain).then.whatever.doOnSuccess(reactiveMongoDbRepository::save);

换句话说,我是不是被迫在任何地方都使用这个管道来保持响应性,或者以命令的方式执行某些步骤,比如打开对象,处理它,然后把它包装回去?

我知道我的问题似乎很愚蠢,但我根本没有大局观,阅读有关它的书籍并没有真正帮助,请对我温柔一点。 :)

当您需要顺序、异步和惰性执行时使用流水线。在所有其他情况下(当您使用非阻塞代码时)您可以自由选择任何方法,通常最好使用最简单的方法。

顺序非阻塞代码可以组织成函数,您可以使用 map/filter/doOnNext/... 组件将这些代码与反应管道集成。

例如,考虑以下 Order 价格计算代码。

class PriceCalculator {

  private final Map<ProductCode, Price> prices;

  PriceCalculator(Map<ProductCode, Price> prices) {
    this.prices = prices;
  }

  PricedOrder calculatePrice(Order order) { // doesn't deal with Mono/Flux stuff
    Double price = order.orderLines.stream()
      .map(orderLine -> prices.get(orderLine.productCode))
      .map(Price::doubleValue)
      .sum();
    return new PricedOrder(order, price);
  }
}

class PricingController {

  public Mono<PricedOrder> getPricedOrder(ServerRequest request) {
    OrderId orderId = new OrderId(request.pathVariable("orderId"));
    Mono<Order> order = orderRepository.get(orderId);
    return order.map(priceCalculator::calculatePrice)
  }
}