webflux 大佬求教,编程范式疑问

2021-09-23 00:18:25 +08:00
 myCupOfTea

webflux 是不是很容易写出回调地狱啊
话说原本很简单的一个场景,查询 User 和 UserInfo 的信息,然后复制给 OperInfo
webflux 写出来总感觉怪怪的

// mvc
User user = userRepository.findById(xxx);
UserInfo userInfo = userInfoRepository.findById(xxx);
OperInfo operInfo = new OperInfo();
BeanUtils.copyProperties(user, operInfo);
BeanUtils.copyProperties(userInfo, operInfo);
return operInfo;

我 webflux 写成了下面,不知道应该怎么写才是最佳实践

// webflux
Mono<User> user = userRepository.findById(xxx);
Mono<UserInfo> userInfo = userInfoRepository.findById(xxx);
return Mono.zip(user, userInfo).flatmap(data -> {
	User user = data.getT1();
	UserInfo userInfo = data.getT2();
	OperInfo operInfo = new OperInfo();
        BeanUtils.copyProperties(user, operInfo);
	BeanUtils.copyProperties(userInfo, operInfo);
        return operInfo;
})
1655 次点击
所在节点    程序员
4 条回复
myCupOfTea
2021-09-23 00:19:29 +08:00
而且我中间一旦有很多外部调用,回调写到爆炸,好难受
JamesChen
2021-09-23 08:05:45 +08:00
webflux 不容易写出回调地狱。我写了几十 W 行 reactor-core ( webflux 的底层异步实现),基本都没写出过回调地狱。如果有略微“接近”回调地狱的代码,那也是为了减少中间 Publisher ( Mono/Flux )中间对象与对象传递时的开销,如果不关心这些开销,拆成扁平结构也都是没问题的。

具体操作而言,可以把大块的回调函数拆成多个函数,或拆除多个代码逻辑块。如果要看具体代码,可以参考下面这个超长函数,该函数涉及多个异步操作,但是并没有出现回调地狱,代码都比较扁平: https://github.com/turms-im/turms/blob/9e9cd17e3a1bb5fb3cc32519082885b2ac9f0dba/turms-service/src/main/java/im/turms/service/workflow/access/servicerequest/dispatcher/ServiceRequestDispatcher.java#L152

另外,webflux 没人带,或者自己不怎么想深入专研,不太推荐使用,因为很容易就用错了,而且你还不知道。可以考虑等等 loom (估计 2 年后的时)。
zhenjiachen
2021-09-23 10:50:19 +08:00
如果不想写回调地狱可以看看 kotlin 的 coroutines,在方法上加个 suspend 配合 reactor 就像写同步代码一样。
myCupOfTea
2021-09-23 13:05:42 +08:00
@JamesChen 好的,谢谢拉,我只是要改造 spring cloud gateway 不得已要写

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/803507

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX