为什么当前场景下combineLatest能运行但forkJoin不生效?
RxJS combineLatest替换为forkJoin不触发订阅的原因
核心原因是两个操作符的触发逻辑完全不同:
combineLatest触发规则:所有传入的Observable都至少发出过1个值后,只要任意一个Observable发出新值,就会把所有流的最新值组合后传给订阅回调,不需要等流完成。forkJoin触发规则:必须等所有传入的Observable**全部完成(complete)**后,才会一次性输出每个流的最后一个发出值,只要有一个流没有完成,订阅回调就永远不会触发。
你当前代码中封装的addOneClick$是基于fromEvent实现的DOM点击监听流,这类事件监听流本身是永不主动完成的,你添加的startWith(0)只是让流在初始化时主动发出了0这个初始值,并没有改变流永不完成的特性,因此forkJoin会一直等待两个流完成,自然不会触发订阅。
补充说明
- 你当前的实时计数场景本身就适合用
combineLatest:搭配startWith(0)可以实现页面加载就渲染初始0值,每次点击按钮实时更新计数的效果,完全符合需求。 - 如果要测试forkJoin的效果,可以给
addOneClick$添加触发流完成的操作符,比如:
const addOneClick$ = (id) => fromEvent(document.getElementById(id), "click").pipe( mapTo(1), scan((acc, curr) => acc + curr, 0), startWith(0), take(2) // 流总共发出2个值(初始0+1次点击的1)后自动完成 );
修改后分别点击一次红、黑按钮,两个流都完成后forkJoin就会触发回调输出最终的计数结果,但这种写法失去了实时更新的能力,不适合当前场景。
内容的提问来源于stack exchange,提问作者I_sam
相关产品推荐
相关产品推荐

