当另一个Observable提供值

时间:2015-06-24 11:51:51

标签: .net system.reactive

当另一个Observable提供值时,我需要忽略Observable值一段时间

目前,我的实现使用变量来控制阻塞(或忽略)。

bool block = false;

var blocker = observable1.Do(_ => block = true )
                         .Throttle( _ => Observable.Timer(_timeToBlock)
                         .Subscribe( _ => block = false ));

var receiver = observable2.Where( i => !block && SomeCondition(i) )
                          .Subscribe( i=> EvenMoreStuff(i) );

通过组合这两个可观察对象,有更多的Rx方法吗?

编辑:对拦截器订阅的小改变

2 个答案:

答案 0 :(得分:2)

第一项任务是将block变量表示为可观察的。

IObservable<bool> blockObservable = observable1
    .Select(x => Observable.Concat(
        Observable.Return(true),
        Observable.Return(false).Delay(_timeToBlock)))
    .Switch()
    .DistinctUntilChanged();

每次observable1发出一个值时,我们都会选择一个发出true的观察点,等待_timeToBlock,然后发出falseSwitch只是总是切换到最近的那些可观察对象。

这是一张大理石图。我们假设_timeToBlock长3个字符。

observable1      -----x--xx-x-----x-----
select0               T--F
select1                  T--F
select2                   T--F
select3                     T--F
select4                           T--F
switch           -----T--TT-T--F--T--F--
blockObservable  -----T--------F--T--F--

现在,我们可以使用Zip的{​​{1}}值MostRecent blockObservable您的值序列。

var receiverObservable = observable2
    .Zip(blockObservable.MostRecent(false), (value, block) => new { value, block })
    .Where(x => !x.block)
    .Select(x => x.value);

答案 1 :(得分:1)

作为使用一次性用品的替代方法,您可以创建一个小的扩展方法:

public static IObservable<TResult> Suppress<TResult, TOther>(
                                    this IObservable<TResult> source, 
                                         IObservable<TOther> other,
                                         TimeSpan delayFor)
{
  return Observable.Create<TResult>(observer => {
    var published = source.Publish();
    var connected = new SerialDisposable();
    Func<IDisposable> connect = () => published.Subscribe(observer);
    var suppressor = other.Select(_ => Observable.Timer(delayFor)
                                .Select(_2 => connect())
                                .StartWith(Disposable.Empty))
    .Switch();

    return new CompositeDisposable(
                connected,
                suppressor.StartWith(connect())
                          .Subscribe(d => connected.Disposable = d),
                published.Connect());
  });
}

这会将源observable转换为ConnectableObservable,然后每次other源发出它都会处理它的订阅,然后在计时器到期时重新连接。