当前位置: 首页 > 知识库问答 >
问题:

WebFlux条件平面映射

宗政卓
2023-03-14

我对webflux比较陌生,我想找到解决方案,在有条件时避免嵌套flatMap:

public Mono<Item> patch(String itemId, PatchSpecs specs) {
return itemRepository.findById(itemId)
        .switchIfEmpty(Mono.error(..)))
        .flatMap(item -> {
            final String brandId = specs.getBrandId();
            if (brandId != null) {
                return brandService.getById(brandId)
                        .switchIfEmpty(Mono.error(..)))
                        .flatMap(brand -> {
                            final String categoryId = specs.getCategoryId();
                            if (categoryId != null) {
                               return categoryService.getById(categoryId)... -> return updateAndSave(..)
                            }
                            return updateAndSave(specs, item, brand, null);
                        });
            }
            else {
                final String categoryId = specs.getCategoryId();
                if (categoryId != null) {
                     return categoryService.getById(categoryId)... -> return updateAndSave(..)
                }
                return updateAndSave(specs, item, null, null);
            }

        });
}

如何防止这种分支条件平面映射混乱?我无法想象如果我在项目中有另一个实体。会有更多嵌套的平面地图?

共有1个答案

淳于俊迈
2023-03-14

如果我理解你的代码很好,类别和品牌是项目的可选属性。在这种情况下,我推荐以下方法:

public Mono<Item> patch(String itemId, PatchSpecs specs)
{
    return itemRepository.findById(itemId)
                         .switchIfEmpty(Mono.error(new RuntimeException("Can not find item.")))
                         .flatMap(item -> updateAndSave(specs, item));
}

private Mono<? extends Item> updateAndSave(PatchSpecs specs, Item item)
{
    Mono<Optional<Brand>> brand = getBrand(specs.getBrandId());
    Mono<Optional<Category>> category = getCategory(specs.getCategoryId());

    return Mono.zip(Mono.just(item), brand, category)
               .flatMap(tuple -> updateAndSave(specs, tuple));
}

private Mono<Optional<Brand>> getBrand(String inputBrandId)
{
    return Mono.justOrEmpty(inputBrandId)
               .flatMap(brandId -> brandService.getById(brandId)
                                               .switchIfEmpty(Mono.error(new RuntimeException("Can not find brand."))))
               .map(Optional::of)
               .defaultIfEmpty(Optional.empty());
}

private Mono<Optional<Category>> getCategory(String inputCategoryId)
{
    return Mono.justOrEmpty(inputCategoryId)
               .flatMap(brandId -> categoryService.getById(brandId)
                                                  .switchIfEmpty(Mono.error(new RuntimeException("Can not find brand."))))
               .map(Optional::of)
               .defaultIfEmpty(Optional.empty());
}

private Mono<Item> updateAndSave(PatchSpecs specs, Tuple3<Item, Optional<Brand>, Optional<Category>> tuple)
{
    Item item = tuple.getT1();
    Brand brand = tuple.getT2().orElse(null);
    Category category = tuple.getT3().orElse(null);

    // TODO do update and save here
    return null;
}

这样它将更加可扩展,不需要重复和嵌套条件。请验证它如您所期望的那样工作。

 类似资料:
  • 我有一个场景,其中第二个单声道依赖于first stMono和ThridMono调用依赖于第二个单声道输出。 我写的代码如下。 我怎样才能避免这里的第二个平面图?。有没有办法在没有嵌套平面图的情况下做到这一点。我应该只在满足条件的情况下调用serrdMono。

  • 如果我执行以下“连接”两个流的代码 < li >首先通过平面映射< code >流 我在两种情况下都获得了相同的正确结果,但过滤操作的次数不同。 我在两种情况下都得到了预期的结果(3)。但是,第一个操作对集合的每个元素应用第一个过滤器,而第二个操作在遇到一个过滤器时就停止。输出是: 为什么两者之间的行为有所不同?JDK代码在第一个场景中是否可以改进为与第二个场景中一样高效,或者是否有一些东西使其不

  • 我有一个包含240个项目的列表,使用完整发送此列表需要1个多小时。 所以我跟着这篇文章同时发送,以尽量减少响应时间,但是里面的代码永远不会执行:

  • 每次我认为我理解了可观测物,但我不太理解可观测物。所以考虑一下我在Angular 4应用程序中使用的代码: 我希望我对代码解释得足够好,所以它的本质是我不想在任何地方使用“订阅”。因为我使用异步管道,所以我希望可以一直观察到。但是,当我使用单(),然后我必须平面映射它,否则它给我一个错误,因为我不能返回可观察 如果我没有把我的问题说清楚,我很抱歉。我的场景是,我基本上需要一个配置设置,我的实际ht

  • 假设我有这样的代码: 输出是相同的线程名称,所以这里没有的好处--我的意思是有一个线程来完成所有的工作。 在内部有以下代码: 我理解强制属性如果“outer”流将是并行的(它们可能会阻塞),“outer”将不得不等待“flatmap”完成,反过来(因为使用了相同的公共池),但为什么总是强制这样做呢? 这是一个可以在以后的版本中改变的东西吗?