覆盖 Subject.next 方法

Override the Subject.next method

我有以下代码,我想在其中覆盖 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

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 以获得最后一个值。为此,我提出了一个 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 to be specific) in this commit- 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);
  };
}

干杯!