RxJS mergeAll工作原理及两类示例异常问题咨询
我来帮你拆解这两个示例里mergeAll的工作逻辑,搞清楚为啥会出现你看到的结果~
示例1:为啥只输出"inner",看不到"first"?
咱们一步步捋代码的逻辑:
- 首先
clicks是个每4秒发射一次"first"的Observable,这部分没问题。 - 然后你用
clicks.map(ev => ...)把每个"first"转换成了一个内部Observable:每1秒发射"inner",总共发10次。这里的关键是:你在map里直接返回了这个内部Observable,完全没把ev(也就是"first")传递下去! - 所以
higherOrder这个Observable发射的内容,不是"first",而是一个个内部Observable实例。 - 当你调用
mergeAll()时,它的作用就是把这些内部Observable“摊平”:订阅每个内部Observable,然后把它们发射的内容(也就是"inner")转发给最终的订阅者。而原来的"first"因为被你在map里丢弃了,根本没进入higherOrder的发射序列,自然不会被输出。
如果想同时输出"first"和"inner",可以调整map的逻辑,把外部值和内部Observable结合起来:
// 修改后的示例1:保留"first"的输出 const clicks = Rx.Observable.interval(4000).map(()=> "first"); const higherOrder = clicks.map((ev) => // 先发射外部的"first",再拼接内部的"inner"序列 Rx.Observable.of(ev).concat(Rx.Observable.interval(1000).map(() => "inner").take(10)) ); const firstOrder = higherOrder.mergeAll(); firstOrder.subscribe(x => console.log(x));
这样每4秒会先输出"first",然后每秒输出"inner",一共10次。
示例2:mergeAll的角色,以及为啥
win是Observable? 先搞懂window操作符的核心作用:它会把源Observable(这里是clicks,也就是keyup事件产生的"Hello"),按照另一个Observable(interval每4秒发射一次)的时机,分割成一个个窗口Observable。每个窗口Observable包含当前时间窗口内,源Observable发射的所有值。
所以你的代码流程是:
clicks.window(interval)返回的是一个高阶Observable:每4秒发射一个窗口Observable,这个窗口Observable里装着过去4秒内你按键盘产生的"Hello"。- 你接下来的
map(win => win.take(1)),是对每个窗口Observable做处理:只取这个窗口里的第一个"Hello"。这里的win本身就是Observable,因为window发射的就是Observable,不是具体的"Hello"值。 - 最后
mergeAll()的作用,就是把这些窗口Observable摊平:订阅每个窗口Observable,把它们内部的"Hello"值取出来,转发给最终的订阅者——这就是你看到的"Result Hello"。
如果没有mergeAll(),result会是一个发射Observable对象的高阶Observable,你订阅它的话,得到的会是一个个Observable实例,而不是"Hello"。mergeAll()的核心使命就是把“Observable的Observable”转换成直接发射具体值的Observable。
内容的提问来源于stack exchange,提问作者softshipper
相关产品推荐
相关产品推荐

