Webflux 实现异步方法中进行异步调用

本文介绍了在Spring Webflux项目中遇到的异步调用问题。在尝试从多个表获取并封装数据时,初始方法导致异步结果未能正确返回。通过不断尝试,作者记录了一种能正确处理异步调用的实现方式,尽管对Webflux的底层原理尚未完全理解。此过程对于理解和优化Webflux应用的异步处理具有参考价值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  公司的新项目采取spring webflux 的架构,之前没有学习过,刚开始学习的时候,跑通demo 的时候,觉得貌似挺简单的,spring 封装得跟mvc一样,使用者完全无缝感知,框架内部自己完成了异步调用的逻辑,单独使用flux 和mono的时候,还相对简单。

   现在有个场景是,我需要从表a里取数据,然后根据a中的关联id 分别从b和c 表取数据,最后封装数据;

  一开始的写法,发现返回的结果中,title 和num 并没有值,日志中,异步调用的结果是在结果返回之后复制的

return articleRepository.findAll().map(article -> {
            ArticleVO articleVO = new ArticleVO();
            articleVO.setId(article.getId());
            articleVO.setName(article.getName());
            return articleVO;
        }).map(articleVO -> {
            articleTitleRepository.findByArticleId(articleVO.getId()).subscribe(articleTitle -> articleVO.setTitle(articleTitle.getTitle()));
            return articleVO;
        }).map(articleVO -> {
            articleExtRepository.findByArticleId(articleVO.getId()).subscribe(articleExt -> articleVO.setNum(articleExt.getNum()));
            return articleVO;
        });

后来各种尝试会返回的方法,目前在学习阶段,对webflux 还不是太熟悉,所以相关的原理还没有明白,先记录下来,等理解了再看

return articleRepository.findAll().map(article -> {
            ArticleVO articleVO = new ArticleVO();
            articleVO.setId(article.getId());
            articleVO.setName(article.getName());
            return articleVO;
        }).flatMap(articleVO -> {
            return articleTitleRepository.findByArticleId(articleVO.getId()).switchIfEmpty(Mono.just(new ArticleTitle())).map(articleTitle -> {
                articleVO.setTitle(articleTitle.getTitle());
                return articleVO;
            });
        }).flatMap(articleVO -> {
            return articleExtRepository.findByArticleId(articleVO.getId()).switchIfEmpty(Mono.just(new ArticleExt())).map(articleExt -> {
                articleVO.setNum(articleExt.getNum());
                return articleVO;
            });
        });

另一种写法:

return articleRepository.findAll().map(article -> {
            ArticleVO articleVO = new ArticleVO();
            articleVO.setId(article.getId());
            articleVO.setName(article.getName());
            return articleVO;
        }).flatMap(articleVO -> {
            Mono<ArticleTitle> articleTitleMono = articleTitleRepository.findByArticleId(articleVO.getId()).defaultIfEmpty(new ArticleTitle());
            Mono<ArticleExt> articleExtMono = articleExtRepository.findByArticleId(articleVO.getId()).defaultIfEmpty(new ArticleExt());

            return Mono.zip(articleTitleMono, articleExtMono).map(objects -> {
                articleVO.setNum(objects.getT2().getNum());
                articleVO.setTitle(objects.getT1().getTitle());
                return articleVO;
            });
        });

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值