每当流B发生时,我想停止流A以获得一个通知。两个流都将保持在线状态,并且永远不会完成。
A: o--o--o--o--o--o--o--o--o
B: --o-----o--------o-------
R: o-----o-----o--o-----o--o
或
A: o--o--o--o--o--o--o--o--o
B: -oo----oo-------oo-------
R: o-----o-----o--o-----o--o
答案 0 :(得分:2)
当observable很热(并且没有refCount
)时,此解决方案将起作用:
streamA
.takeUntil(streamB)
.skip(1)
.repeat()
.merge(streamA.take(1))
.subscribe(console.log);
.takeUntil(streamB)
:生成流A
生成一个值B
。.skip(1)
:make stream A
在启动时跳过一个值(或.repeat()
的结果)。.repeat()
:make stream A
无限期重复(重新连接)。.merge(streamA.take(1))
:在流的开头抵消.skip(1)
的影响。每5秒跳过一个流的示例:
var streamA,
streamB;
streamA = Rx.Observable
.interval(1000)
.map(function (x) {
return 'A:' + x;
}).publish();
streamB = Rx.Observable
.interval(5000);
streamA
.takeUntil(streamB)
.skip(1)
.repeat()
.merge(streamA.take(1))
.subscribe(console.log);
streamA.connect();
您还可以使用此沙箱http://jsbin.com/gijorid/4/edit?js,console在运行代码时在控制台日志中执行BACTION()
,以手动将值推送到streamB
(这有助于分析码)。
答案 1 :(得分:2)
以下是我为a similar question所做的SkipWhen
运算符版本(不同之处在于,在原始版本中,多个“B”将跳过多个“A”):
public static IObservable<TSource> SkipWhen<TSource, TOther>(this IObservable<TSource> source,
IObservable<TOther> other)
{
return Observable.Create<TSource>(observer =>
{
object lockObject = new object();
bool shouldSkip = false;
var otherSubscription = new MutableDisposable();
var sourceSubscription = new MutableDisposable();
otherSubscription.Disposable = other.Subscribe(
x => { lock(lockObject) { shouldSkip = true; } });
sourceSubscription.Disposable = source.Where(_ =>
{
lock(lockObject)
{
if (shouldSkip)
{
shouldSkip = false;
return false;
}
else
{
return true;
}
}
}).Subscribe(observer);
return new CompositeDisposable(
sourceSubscription, otherSubscription);
});
}
如果当前实现成为瓶颈,请考虑更改锁实现以使用ReaderWriterLockSlim
。