【问题标题】:Extend RxJS Observable class with operators使用操作符扩展 RxJS Observable 类
【发布时间】:2017-05-13 00:36:32
【问题描述】:

Observable 类如何通过应用内置的 RxJS 运算符来扩展它?

我想做这样的事情:

class TruthyObservable extends Observable {
  constructor(subscriber) {
    super(subscriber);

    return this.filter(x => x);
  }
}

class TruthyMappedObservable extends TruthyObservable {
  constructor(subscriber) {
    super(subscriber);

    return this.map(x => `'${x}'`);
  }
}

这可以在没有构造函数返回的情况下完成吗?

【问题讨论】:

  • 您希望在哪里添加.filter(x => x);?如果您尝试始终将标准 RxJS 运算符附加到您的自定义运算符,我会理解的。
  • @martin 我希望该运算符将在类实例化时添加,在任何其他运算符之前。
  • 运算符不是扩展Rx.Observable 的类。这是原型上的一种方法。无论如何,我猜你的意思是this.filter(Boolean)
  • @torazaburo 是的。这个问题不仅限于filter,例如,它就在那里。

标签: javascript typescript ecmascript-6 rxjs rxjs5


【解决方案1】:

这在很大程度上取决于您想要做什么,但假设您要创建一个 TruthyObservable,其行为与默认 Observable.create(...) 非常相似,但只传递偶数:

import { Observable, Observer, Subscriber, Subject, Subscription } from 'rxjs';
import 'rxjs/add/operator/filter';

class TruthyObservable<T> extends Observable<T> {

    constructor(subscribe?: <R>(this: Observable<T>, subscriber: Subscriber<R>) => any) {
        if (subscribe) {
            let oldSubscribe = subscribe;
            subscribe = (obs: Subscriber<any>) => {
                obs = this.appendOperators(obs);
                return oldSubscribe.call(this, obs);
            };
        }

        super(subscribe);
    }

    private appendOperators(obs: Subscriber<any>) {
        let subject = new Subject();

        subject
            .filter((val: number) => val % 2 == 0)
            .subscribe(obs);

        return new Subscriber(subject);
    }

}

let o = new TruthyObservable<number>((obs: Observer<number>) => {
    obs.next(3);
    obs.next(6);
    obs.next(7);
    obs.next(8);
});

o.subscribe(val => console.log(val));

这会打印到控制台:

6
8

观看现场演示:https://jsbin.com/recuto/3/edit?js,console

通常继承 Observable 的类会覆盖 _subscribe() 方法,该方法实际上在内部进行订阅,但在我们的例子中,我们希望使用回调,我们可以自己发出值(因为这个 Observable 本身不会发出任何东西)。方法_subscribe()_subscribe 属性所掩盖(如果它存在),因此如果我们只是覆盖此方法,我们将无法向其附加任何运算符。这就是为什么我用另一个函数将_subscribe 包装在构造函数中,然后通过SubjectappendOperators() 方法中与filter() 链接传递所有值。请注意,我在obs = this.appendOperators(obs) 处将原始观察者替换为Subject

最后,当我打电话时。 obs.next(3); 实际上,我将值推送到 Subject 过滤它们并将它们传递给原始 Observer

【讨论】:

    【解决方案2】:

    我认为您可以通过自定义运算符获得所需的内容:

        Observable.prototype.truthy = function truthy() {
            return this.filter(x => x);
        }
    

    【讨论】:

    • 谢谢,可以这样。但是,问题是如何通过继承来完成,我也不打算修改原型。
    • @estus,你能给我提供TruthyObservable 的用例/示例吗?
    • 我主要想了解如何正确扩展 RxJS,尤其是Observable。我打算将扩展 Observable 用作 Angular 2 服务,它与 Typescript 中的类配合得更好。
    • @estus 继承自什么?运算符不是对象或类,也没有基类;它们只是方法。您可以扩展 Rx.Observable 以创建具有某种修改行为的可观察对象,而不是运算符。
    • @torazaburo 继承自 Observable。我不打算扩展运算符,只需将它们应用于this 实例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    • 2017-12-01
    • 1970-01-01
    • 2023-03-13
    相关资源
    最近更新 更多