1
BBCCBB 2023-10-07 23:50:59 +08:00
可以先理解下 js 里最开始的 callback hell, 然后再看看 Promise 的出现解决了 js 的什么问题. Promise 可以理解成一个最简单的响应式..
一定程度上解决了 callback hell, 然后加了一些方便开发的 operator 方法. 不建议看这个东西.. 协程才是正路. |
2
b1t 2023-10-08 00:26:53 +08:00
我看 Spring Cloud Gateway 的时候跟你的感觉是一模一样的,然后我就放弃了
|
3
b1t 2023-10-08 00:28:28 +08:00
op 如果找到响应式编程的学习方法,记得 @一下我(逃
|
4
statumer 2023-10-08 02:32:16 +08:00
Project Reactor 这些东西就是 monad 在 Java 里的实现。需要这个东西的根本原因是 Java 没有协程,非得用纯函数这种不自然的形式构造状态机。
现在没什么学的必要了,如果进展理想的话协程在 Java 世界中会迅速普及。 btw ,回复一下主楼里的问题,你转述的 gpt 的说法是完全错误的,可以自己找本书看或者看 Project Reactor 的 reference ,第三章很好地阐释了基本思想。 |
5
weijancc 2023-10-08 08:08:29 +08:00
在 Spring Cloud Gateway 上开发的代码看着真恶心
|
6
SilenceLL 2023-10-08 08:19:40 +08:00
原来大家都看着难受,说明是真的难受
|
7
iOCZ 2023-10-08 08:34:30 +08:00
不要过分依赖 GPT ,它撒起谎来还有板有眼的
|
8
chendy 2023-10-08 08:55:00 +08:00
可以在业务不复杂,对性能又有一些要求的场景使用
不能用同步语法写异步就是坐大牢 |
9
iovekkk 2023-10-08 08:55:07 +08:00
按我的理解,响应式编程的意义就是可以把某一个代码块或者函数当做参数,而这一段代码块或者函数的逻辑,可以放到任何地方去实现
|
10
mgcnrx11 2023-10-08 09:09:49 +08:00
因为 op 把“响应式 Reactive” 和 “异步非阻塞” 的概念 混淆为 它两个是一个意思了
Project Reactor 的响应式里面,当 subscribe 时,一系列的操作会一个接着一个去执行。但这些操作都是我们自己写的代码,还是需要确保这里自己写的代码是“非阻塞”的才行。否则,就会像你举例的一样,sleep(2000L)后发现阻塞了。 还有的是,除非显式的调用 publishOn / subscribeOn 等方法呢,否则都是在调用 subscribe 的当前线程上执行的。也就会造成该线程被 sleep 阻塞起来的感觉 > 但是 gpt 告诉我 filter 之间可以是并行的 这是错误的 |
11
afeiche 2023-10-08 09:13:06 +08:00
spring 那一套和阻塞线程参合在一起,不太好理解,你可以看看 vert.x ,参考 nodejs 搞的,理解起来会容易一点,我没看你过 project reactor ,估计和 vert.x 差不多,底层应该都是 netty 。
|
12
ccde8259 2023-10-08 09:14:43 +08:00 via iPhone
想搞响应式编程的话,以生产者-消费者模型为基础,得先入门一下函数式编程,再开始理解值容器也就是 Monad……太难了还是别学了
|
13
des 2023-10-08 09:19:33 +08:00 via iPhone
我还以为只有我一个人是这样呢,看的难受
|
14
msaionyc 2023-10-08 09:25:42 +08:00
理解起来确实费劲,从声明,订阅( subscribe ),请求,执行,正向->逆向->正向->逆向,最后又到正向执行,太绕了。
而且也不好 debug |
15
Helsing 2023-10-08 09:34:53 +08:00 via iPhone
|
16
srx1982 2023-10-08 09:47:49 +08:00
简单的需求还行,如果需求复杂,还要在不同阶段读取多种数据源,那就麻烦了
|
17
mikasa1024 2023-10-08 10:08:49 +08:00
之前基于 srping gateway 开发了一个网关管理系统,感受就是业务很难写,到最后只是连着数据库做了个简单的增删查改,然后和网关路由同步起来
下次有这种需求,我会选择使用 openresty 或者 apisix ,选择 openresty 用 lua 开发的体验应该也比 gateway 的这个响应式强 |
18
Leviathann 2023-10-08 10:31:19 +08:00
Brian Goetz: "I think Project Loom is going to kill Reactive Programming"
|
19
GiantHard 2023-10-08 10:52:44 +08:00
> 比如在数据流上设定操作符(如 flatMap),然后当调用 subscribe 时,这一系列操作符就会被执行。但这个和普通的回调有什么区别呢
没有区别,这些操作符就是在帮助你设置回调函数 > 为啥说它是异步非阻塞的 因为 Operator 的执行线程可以由 Scheduler 决定,所以说 Rx (ReactiveX, 响应式编程 API) 可以实现异步非阻塞 https://projectreactor.io/docs/core/release/api/reactor/core/scheduler/Scheduler.html > 一个 filter 返回的 Mono 的 flatMap 中写下 Thread.sleep(2000L),发现在该 filter 后面的所有 filter 也被阻塞了 Thread.sleep 是「阻塞的 api 」,你可以试试使用 Rx 的 delay https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html#delay-java.time.Duration- 除了 Thread.sleep 之外,Java 世界中有很多库的 API 都是阻塞的,要在 Rx 世界中流畅使用,得自己找对应的 Rx 实现 |
20
yazinnnn0 2023-10-08 11:57:04 +08:00
|
21
Hugehard 2023-10-08 14:07:04 +08:00
不只是看不懂,debug 我都搞不懂,目前在看一个项目,全靠 gpt 理解
|
22
yuhongtai114514 OP @BBCCBB 感谢,这就去看看~
|
23
yuhongtai114514 OP @b1t ok ~
|
24
yuhongtai114514 OP @statumer 好的,非常感谢,看来我过于相信 gpt 了(´_ゝ`),直接绕晕
|
25
yuhongtai114514 OP @GiantHard 帮助很大! 我去看看 Rx ,感谢解惑🙏
|
26
yuhongtai114514 OP @yazinnnn0 我之前一直以为这两个强关联🥹
|
27
imaple 2023-10-08 16:06:50 +08:00
确实有点难, 而且很难调试, 爆炸
|
28
cloud107202 2023-10-08 16:49:45 +08:00
推荐精读一下这个 reddit 评论 https://www.reddit.com/r/java/comments/96p88f/comment/e42vqrx/
|
29
unco020511 2023-10-08 17:43:55 +08:00
其实 rxjava 更多使用是在界面程序的,比如移动端应用,主线程不能做耗时操作,经常需要使用 callback,需要频繁切换线程.后台我感觉必要性没有那么大
|
30
vivisidea 2023-10-08 17:53:25 +08:00
subscribe / subscribeOn 调试起来要疯,我们之前有个项目试点了一下响应式,写的人觉得很爽,其它开发一脸懵,维护很麻烦,后来还是抛弃了
|
31
Huelse 2023-10-08 18:43:50 +08:00
不如学函数式编程,其核心思想要普遍的多。
|
32
rrfeng 2023-10-08 19:16:55 +08:00
当年写 angular 强行学习了一下 rxjs ,学起来太难,但是会了确实很好用(然而已经忘光了)。
前提是 js ,java/go 还是协程走起吧。 |
33
ychost 2023-10-08 21:07:43 +08:00
首先得理解什么是 IO ,IO 底层如何实现「同步非阻塞」的,然后再来看 flatMap 操作符的用处,如果不用 flatMap 自己该如何处理这些 IO 回调,如果业务里面 IO 少的话没必要上 reactor
|
34
mxT52CRuqR6o5 2023-10-08 21:12:48 +08:00 via Android
学过 rxjs 也实际应用过,没觉得有多好用(没有必要的话就不要去用),但如果有复杂的异步场景的话,不用 rx 写起来感觉就是寸步难行
|
35
Dlin 2023-10-08 22:50:20 +08:00 via Android
个人也觉得响应式是一种编程思想。是某个事务满足触发操作时触发的同步回调。每个 filter 只是这次触发中的执行过程中的一部分。说它异步,其实只是这一过程并非是人为有意去调用的。而是系统自己去调用的(subscribe)
|
36
comingnine 2023-10-09 01:42:37 +08:00 via Android
感觉解藕真不好调试
|
37
xarthur 2023-10-09 03:18:25 +08:00 via iPhone
其实你需要去了解一些函数式编程,响应式只是很自然的引用……
|
38
zhuangzhuang1988 2023-10-09 06:19:49 +08:00 via Android
https://www.bennadel.com/blog/4519-replacing-rxjs-with-a-state-machine-in-javascript.htm
想象成状态机试试 不过状态机会要写很多代码 rx 帮忙解决了 |
39
ma836323493 2023-10-09 10:22:53 +08:00
看看郭神 的 第一行代码, 了解这个应该轻松电吧
|
40
f14g 2023-10-09 10:23:50 +08:00 via Android
以前也是不理解这个,后来学校教 Verilog 的时候遇到了“线变量”这种东西,当时就理解了“响应式编程”了。
|
41
nothingistrue 2023-10-09 14:02:59 +08:00 2
六,响应式编程,对应的编程概念是「流」,现实概念有个跟起非常像的,「流水线」。如果要搞这个,首先要把「流」搞清楚。Java8 的 Stream 可以用来入门。Kettle 、Spring Batch 可以用来练手。你最起码是 kettle 或者 Spring Batch (高级流应用,不能是一个处理器转发然后又回到普通代码去处理了) 用得比较熟悉了,才能去接触响应式编程。另外,你也可以直接从函数式编程、数据流,这些数学理论入手,不过前提是要先清空 C 、C++、Java 等全部常规编程习惯。
一到五跑题了,留着备用看吧。 一,同异步跟是否阻塞,不是一词两用,而是有关联的两个概念。 二,阻塞针对的不是当前过程,而是使用同一资源的多个过程之间的协作方式。通常都是 IO 比计算慢,故常见的阻塞是针对 IO 的阻塞。一个 IO 通道,如果只允许同时最多一个过程使用它,在该过程使用它期间其他过程只能等,那么这就是阻塞的。如果允许同时多个过程使用它,那么这是非阻塞的。 三,同步异步,针对的是调用者和被调用者之间的协作过程。如果被调用者不做完就不回复,同时调用者还一直等着它,那么这是同步的。如果被调用者没处理完就提前做个特殊回复,同时调用者认可这种特殊回复,那么这是异步调用。如果调用者这收到异步特殊回复之后,又再继续等待这个特殊回复转换成完整回复,那么这是异步之后的回转同步,或者,整体上来说,这还是同步调用。 四,再往外看调用者、非调用者的宿主程序,这时候同异步跟阻塞有了关联。如果把调用者宿主程序认为资源,调用关系——被调用者的执行行为认为处理过程,那么同步调用是阻塞的,异步调用是非阻塞的。 五,同步还是异步,技术上由被调用者决定,但业务上由有调用者决定。如果调用者实时关心回复结果,那么它永远要是同步调用,即使被调用者技术上异步,最终也要通过异步转回同步来变成同步。异步编程中,如何异步从来都不是关键,如何异步转会同步,获取去掉不必要的业务同步,才是关键。 |
42
yuhongtai114514 OP @xarthur ok~之前还没正式看过函数式调用,只知道是把函数传来传去
|
43
4kingRAS 2023-10-11 11:11:14 +08:00
你真正要看阻不阻塞要看线程 id ,当前代码运行在哪个线程
|
44
hdfg159 329 天前 via iPhone
rxjava 玩一轮,你就懂了
|