我尝试使用windowCount将可观察值分组,并为每个组发送请求的每个值。
然后,连接这些组,以便下一组的请求无法启动在当前组的请求未完成之前。
问题是某些值被跳过。
这是我的代码。
(我' m没有在这里进行实际的ajax调用,但是Observable.timer应该用于示例)。
Observable.interval(300)
.take(12)
.windowCount(3)
.concatMap(obs => {
return obs.mergeMap(
v => Observable.timer(Math.random() * 1500).mapTo(v)
);
})
.do(v => console.log(v))
.finally(() => console.log('fin'))
.subscribe();
我尝试通过手动创建组来替换windowCount。而且效果很好。不会跳过任何值。
Observable.interval(900)
.take(4)
.map(i => Observable.interval(300).take(3).map(j => j + i * 3))
.concatMap(obs => {
return obs.mergeMap(
v => Observable.timer(Math.random() * 1500).mapTo(v)
);
})
.do(v => console.log(v))
.finally(() => console.log('fin'))
.subscribe();
我的印象是windowCount应该以相同的方式对发射的值进行分组。
但是,显然它会做其他事情。
我会非常感谢对其行为的任何解释。
谢谢!
答案 0 :(得分:0)
缺少的值是使用热的可观察量(Observable.interval(300)
)继续输出您未存储以供使用的值。
以下是您的代码的略微简化版本,它还记录了数字的发布时间。我将Math.random()
替换为1
,以便输出具有确定性。我还在jsbin中加载了代码供您试用:
https://jsbin.com/burocu/edit?js,console
Observable.interval(300)
.do(x => console.log(x + ") hot observable at: " + (x * 300 + 300)))
.take(12)
.windowCount(3)
.do(observe3 => {observe3.toArray()
.subscribe(x => console.log(x + " do window count at: " + (x[2] * 300 + 300)));})
.concatMap(obs => {
return obs.mergeMap(
v => Observable.timer(1 * 1500).mapTo(v)
)
.do(v => console.log(v + " merge map at: " + (v * 300 + 300 + 1500)));
})
.finally(() => console.log('fin windowCount'))
.subscribe();
导致下面的输出。请注意,当其他运算符仍在处理时,热点可观测值会继续前进。
这就是让您感觉价值被放弃的印象。你可以看到windowCount(3)
正在做你认为的,而不是 。
"0) hot observable at: 300"
"1) hot observable at: 600"
"2) hot observable at: 900"
"0,1,2 do window count at: 900"
"3) hot observable at: 1200"
"4) hot observable at: 1500"
"5) hot observable at: 1800"
"3,4,5 do window count at: 1800"
"0 merge map at: 1800"
"6) hot observable at: 2100"
"1 merge map at: 2100"
"7) hot observable at: 2400"
"2 merge map at: 2400"
"8) hot observable at: 2700"
"6,7,8 do window count at: 2700"
"9) hot observable at: 3000"
"10) hot observable at: 3300"
"11) hot observable at: 3600"
"9,10,11 do window count at: 3600"
" do window count at: NaN"
"8 merge map at: 4200"
"fin windowCount"
修改:进一步说明......
在windowCount(3)
之后,系统会调用concatMap
。 concatMap
是map
和concatAll
的组合。
连接源发出的每个Observable(更高阶 可观察的),以连续的方式。它订阅了每个内心 Observable 仅在前一个内部Observable完成(强调添加)之后,和 将所有值合并到返回的observable中。
所以,看看上面的输出,我们看到第一个windowCount(3)
值[0,1,2]在1800到2400之间发出。
请注意,第二个windowCount(3)
值[3,4,5]是在1800发出的。concatAll
在[3,4,5]发出时尚未准备订阅,因为之前的内部Observable还没有完成。所以这些价值被有效地贬低了。
接下来,请注意前一个内部Observable [0,1,2]在2400完成。concatAll
订阅2400。
出现的下一个值是2700处的值8(订阅从2400开始后300ms)。然后,值{8}由mergeMap
在4200处输出,因为从订阅起始点2400开始的间隔延迟为300,然后是1500的定时器延迟(即2400 + 300 + 1500 = 4200)。
在此之后,序列完成,因此不会再发出任何值。
如果需要更多说明,请添加评论。