【问题标题】:Override the Subject.next method覆盖 Subject.next 方法
【发布时间】:2021-05-16 19:55:49
【问题描述】:

我有以下代码,我想在其中覆盖 next 以获得一些自定义逻辑。它不能以这种方式工作,但只有在 next 是具有箭头功能的属性时才有效。背后的原因是什么?

export class Store<T> extends ReplaySubject<T | undefined> {
  next(value?: T) {
    console.log("do something in my code");
    super.next(value);
  }
}
export class Store<T> extends ReplaySubject<T | undefined> {
  next = (value?: T) => {
    console.log("do something in my code");
    super.next(value);
  };
}

https://stackblitz.com/edit/typescript-override-subject-next

【问题讨论】:

  • 主题可以是Observer,所以这是意料之中的,但是当涉及到ReplaySubject时,它似乎没有实现SubjectLike。这里有点困惑......

标签: typescript rxjs subject


【解决方案1】:

Subject(和 Observables)采用带有 next 之类的方法的 Observer 对象:

const observer = {
  next: () => {},
  error: () => {},
  complete: () => {},
};

您可以将此对象提供给 Subject(最好是 Observable),而不是扩展它:

const subject = new Subject();

const observer = {
  next: (val) => { ... custom logic };
  < ... > 
}

subject.asObservable().subscribe(observer);

【讨论】:

  • 如果不符合您的需求,请分享原因
  • 你说得有道理,但我正在扩展 ReplaySubject,它具有我应该能够覆盖的 next 方法。我的问题是为什么我不能这样做......通过 RxJs 代码我看到它应该是可能的,看不出它为什么不起作用。
  • ReplaySubject 已经扩展了 Subject,所以你需要 mixins(不过我自己从未使用过这种技术)
【解决方案2】:

今天,我最终还扩展了ReplaySubject 以获得最后一个值。为此,我提出了 PR-https://github.com/ReactiveX/rxjs/pull/6652/files,但同时为了解决我的项目,我扩展了ReplaySubject,我也遇到了同样的情况; next 未被覆盖。

我把自己逼疯了,为什么会这样。我跳入源代码,看到在 RxJS 6.x 版本中,next 方法 id 被函数赋值覆盖 - https://github.com/ReactiveX/rxjs/blob/6.6.7/src/internal/ReplaySubject.ts#L31 这就是它没有被覆盖的原因。

根据同一文件的历史记录,我发现此行为在 v7.x 中(具体为 7.0.0-beta.6)在此提交-https://github.com/ReactiveX/rxjs/commit/f1dcada1e1838ffb01cd0dac60340c6fa068f3cf#diff-a287f66fc20bf26caa2f42935756aa6a094f400e91d6b4a388aee4e4e11675c4 中发生了变化。

所以你必须升级到 RxJS 7.x 版本才能让它工作。

如果您无法升级到 7.x 版本-这里是解决方法-

export class Store<T> extends ReplaySubject<T | undefined> {

  private originalNext: any;

  constructor(bufferSize: number, windowTime: number) {
    super(bufferSize, windowTime);
    this.originalNext = super.next;
    this.next = this.emit;
  }

  private emit(value?: T): void {
    console.log("do something in my code");
    super.next(value);
  };
}

干杯!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-21
    • 1970-01-01
    • 2016-03-06
    • 2018-03-27
    • 2014-05-27
    • 2014-01-04
    • 2021-11-11
    • 2010-11-16
    相关资源
    最近更新 更多