如何在流B发生时抑制流A的下一个事件

时间:2011-05-07 22:44:28

标签: system.reactive rxjs

每当流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  

2 个答案:

答案 0 :(得分:2)

当observable很热(并且没有refCount)时,此解决方案将起作用:

streamA
    .takeUntil(streamB)
    .skip(1)
    .repeat()
    .merge(streamA.take(1))
    .subscribe(console.log);
  1. .takeUntil(streamB):生成流A生成一个值B
  2. .skip(1):make stream A在启动时跳过一个值(或.repeat()的结果)。
  3. .repeat():make stream A无限期重复(重新连接)。
  4. .merge(streamA.take(1)):在流的开头抵消.skip(1)的影响。
  5. 每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