我有两个可观察对象,我想听最后一个发出第一个值的对象,是否有运算符可用于此?像这样:
let obs1 = Rx.Observable.timer(500,500);
let obs2 = Rx.Observable.timer(1000,1000); // I want the values from this one
let sloth = Rx.Observable.sloth(obs1,obs2);
可观察到的树懒将从obs2发出值,因为它是最后发出第一个值的树懒.
如果不是这种情况,还有其他方法吗?
解决方法:
我喜欢您的解决方案(尽管我怀疑如果流很热,您可能永远看不到第一个发出的值-如果源很冷,那么一切似乎都不错).你可以做一个jsfiddle来检查吗?如果您不遗漏任何价值,那么您的解决方案就是最好的.如果这样做,则可以通过将跳过的值添加回源中来进行更正(obs1.take(1).map(val => obs1.startWith(val)).
否则,对于一般的冗长解决方案,此处的关键是您拥有状态,因此还需要扫描运算符.我们用索引标记源,并保持一个状态,该状态代表已经开始的源的索引.当除了一个以外的所有东西都开始时,我们知道一个没有的人的索引,并且我们仅从那一个中选择值.请注意,这应该与来源是冷还是热无关,因为所有内容都是一次通过的,即没有多个订阅.
Rx.Observable.merge(
obs1.map(val => {val, sourceId: 1})
obs2.map(val => {val, sourceId: 2})
obsn.map(val => {val, sourceId: n})
).scan(
(acc, valueStruct) => {
acc.valueStruct = valueStruct
acc.alreadyEmitted[valueStruct.sourceId - 1] = true
if (acc.alreadyEmitted.filter(Boolean).length === n - 1) {
acc.lastSourceId = 1 + acc.alreadyEmitted.findIndex(element => element === false)
}
return acc
}, {alreadyEmitted : new Array(n).fill(false), lastSourceId : 0, valueStruct: null}
)
.map (acc => acc.valueStruct.sourceId === acc.lastSourceId ? acc.valueStruct.val : null )
.filter(Boolean)
也许更短,我不知道.我会试着把它摆弄一下,看看它是否真正起作用,或者在通知我之前您是否这样做.