Rxjs:如何在管道中绑定主题?

时间:2019-06-28 09:06:30

标签: rxjs

我想将主题集成到管道中,以便以后的操作员可以订阅更早的可观察对象。

上下文:我想实现一种更复杂的“反跳”,其中只有某些事件才能阻止某些其他事件。 为此,我首先要重新实现“去抖动”。

这就是我的想法:

DEFAULT

const debounced = myEventStream.pipe( useSubject(futureEvents => pipe( flatFilter( myEvent => race( interval(10).pipe(map(x => true)), futureEvents.pipe(/* filter(...), */ map(x => false)) ) ) )), ); 将为管道的以下阶段提供未来事件的可观察性。因此,如果useSubject存在,则如果间隔先触发,则不过滤事件,但是如果出现新事件,则过滤事件。

这样的flatFilter是否合理-可以工作吗?这样的useSubject是否已经存在?

1 个答案:

答案 0 :(得分:0)

它就像一种魅力:

function mergeFilter<T>(
    predicate: (arg: T) => Observable<boolean>
): MonoTypeOperatorFunction<T> {
    return mergeMap(evt =>
        predicate(evt).pipe(
            take(1),
            filter(e => e),
            map(e => evt)
        )
    );
}

function useSubject<T, O>(
    fn: (o: Observable<T>) => OperatorFunction<T, O>
): OperatorFunction<T, O> {
    return function(input: Observable<T>): Observable<O> {
        const subject = new Subject<T>();
        const observer: PartialObserver<T> = subject;
        return input.pipe(
            tap(observer),
            fn(subject)
        );
    };
}

function debounceTime<T>(time: number) {
    return useSubject<T, T>(futureEvents =>
        mergeFilter(myEvent =>
            race(
                // allow event after 10ms
                interval(10, s).pipe(map(x => true)),
                // discard event when new event arrived
                futureEvents.pipe(map(x => false))
            )
        )
    );
}

这仍然比原始的rxjs去抖动实现要短得多,但是其性能可能会更差。