如何在RxJS中有选择地发出热(共享)可观察对象?

时间:2018-09-18 21:44:25

标签: javascript typescript rxjs observable reactivex

在我的代码中,我有一个热的可观察对象(通过share()运算符传递的冷可观察对象)发出带有标识符的值(即有效载荷类型包含“ id”字符串属性)。然后,一堆观察者根据所述id过滤发射的值。

我现在认为我的代码对性能产生了巨大影响,因为每个观察者都必须过滤发出的每个值。或者,每当我需要新的观察者订阅共享的可观察对象时,都会创建一个新的过滤后的可观察对象。代码看起来像这样:

const source = new Observable();
const sharedObservable = source.pipe(share());
sharedObservable
    .pipe(filter(payload => payload.id === "id1"))
    .subscribe(observerOne);
sharedObservable
    .pipe(filter(payload => payload.id === "id2"))
    .subscribe(observerTwo);
// etc.

我的最初解决方案是创建我自己的热/共享可观察类型,该内部可观察类型基于从ID到应​​接收有效载荷的观察者列表的内部映射来处理过滤。这样可以减少必须为每个订阅的观察者运行某些谓词过滤器功能的成本。在可观察对象的下面看起来像(或模糊地):

class FilteredHotObservable {
    constructor(sourceObservable) {
        this.observerMap = new Map();
        this.source = sourceObservable;
        this.source.subscribe(payload => {
            const observers = this.observerMap.get(payload.id);
            observers.forEach(observer => observer.next(payload));
        });
    }

    subscribe(observer, desiredIdToFilterBy) {
        const observers = this.observerMap.get(desiredIdToFilterBy);
        observers.push(observer);
    }
}

但是,在执行此操作之前,我想知道是否已经存在处理此场景的正确方法。换句话说,RxJS是否已经具有一种机制(例如特殊的Subject,一个奇特的运算符)来促进这种可伸缩的“过滤并共享”的可观察性?

免责声明:上面的代码片段的名称和语法与我的实际操作不符。它们只是本文的示例。

编辑: 这是有关使用filter运算符的排放处理延迟的实际数字。对于“ PostFilterLatency”,发出的有效负载由与共享可观察对象上的单个观察者相对应的ID过滤。对于“ PreFilterLatency”,通过id-> Observer映射手动对发射进行过滤,然后随后使用适当的有效负载调用observer.next()。这些数字是从有效载荷发出到相应观察者对其进行处理所花费的时间(时间以毫秒为单位)。

ObserverCount  PostFilterLatency  PreFilterLatency
-------------  -----------------  ----------------
1              0                  0
10             0                  0
100            0.03               0
1000           0.039              0.001
10000          1.1849             0.0005
100000         19.90902           0.002

编辑:这是我用来运行这些测试的代码的link

0 个答案:

没有答案