如何对我的ReplaySubject的所有发射应用延迟?

时间:2018-09-26 14:00:18

标签: angular typescript rxjs

我想在我的Angular应用中创建一个ReplaySubject,并进行设置,以使观察者订阅它和收到更新之间总是存在延迟。

let delayedReplay = new ReplaySubject(1);

delayedReplay.subscribe((data) => {
  console.log('Got:', data);
});

delayedReplay.next('Test');

我想要对ReplaySubject本身施加延迟,以便上述代码在1秒后记录'Got: Test'

2 个答案:

答案 0 :(得分:4)

您必须将Subjectdelay进行管道传输,并使用产生的Observable进行订阅,同时使用原始的Subject进行发射。

它看起来像这样:

let replay = new ReplaySubject(1);

let delayedReplay = replay.pipe(delay(1000));

delayedReplay.subscribe((data) => {
  console.log('Got:', data);
});

replay.next('Test');

这在所有情况下都应该有效,但是如in this comment所述,也可以lift主题并将结果转换回主题,因为lift实例化了{{1 }}。尽管您可能必须知道Subject的实现以确保类型转换有效,但这可能会导致一些抽象泄漏。

如果要使用它,该解决方案如下所示:

AnonymousSubject

请注意,let delayedReplay = <ReplaySubject> new ReplaySubject(1).delay(1000); // without rxjs-compat in RxJS 6+: // let delayedReplay = <ReplaySubject> new ReplaySubject(1).lift(new DelayOperator(1000)); delayedReplay.subscribe((data) => { console.log('Got:', data); }); delayedReplay.next('Test'); 可能会在RxJS 7中删除。

现在,最后一个选择是扩展ReplaySubject,因此您不必键入强制转换。请注意,这将增加实现与RxJS之间的耦合,并忽略可组合管道的优势。

它看起来像这样:

lift

答案 1 :(得分:0)

如果您希望在订阅时同时发出将来和以前的项目,则会延迟

    this.eventsQueue$ = new ReplaySubject<AnalyticsEvent>();
    this.eventsQueue$.asObservable().pipe(
      concatMap(value => of(value).pipe(delay(2000)))
    ).subscribe((e: AnalyticsEvent) => {
       console.log('event received', e.type);
    });