【问题标题】:Signal when a ReplaySubject has "finished"ReplaySubject 已“完成”时发出信号
【发布时间】:2018-07-25 18:04:38
【问题描述】:

我正在尝试找出一个好方法来表明 ReplaySubject 当前为“空”。

import {ReplaySubject} from 'rxjs/ReplaySubject';
const rs = new ReplaySubject<Object>();

 // ...
constructor(){
  this.sub =  rs.subscribe(...);
}

每次调用构造函数时,它都会重播主题中的所有项目。但是我的问题是 - 是否有一些我们可以听的事件,它告诉我们什么时候主题变空?

我唯一能想到的就是在主题完成后触发一个自定义/不同的事件,如下所示:

rs.next({done:true});

将数据传递给 next() 方法是表明 ReplaySubject (暂时)为空/没有事件的最佳方式吗?

【问题讨论】:

  • 您要查找的内容有点令人困惑。 “完成”是指致电complete()? “空”是指它还没有收到任何next() 电话吗?主题不能通过调用他们的任何方法变为空。
  • “完成”是指这是最后一次在该主题上调用 next()

标签: rxjs rxjs5 angular-observable


【解决方案1】:

因为 Subject 也是一个观察者,所以你可以在最后一次调用 next() 之后调用 complete()。然后你可以用subscribe(...)方法的第三个参数来监听它。

const rs = new ReplaySubject<Object>();
rs.next({a: 1})
rs.complete()

rs.subscribe(
    obj => console.log(obj),
    error => {},
    () => console.log('completed')
);
// Outputs
// {a: 1} completed

【讨论】:

    【解决方案2】:

    现在,我想你可以设置一个辅助 observable 来告诉你最后重播的项目是什么:

    const last$ = rs.replay(1);
    

    然后你只需 combineLatest 并扫描...一旦你到达 last$ 发出的项目,那么你的 ReplaySubject 就完成了重播:

    this.sub = Observable.combineLatest(
      rs,
      last$.take(1)
    ).scan((acc: { item: Object, isReplay: boolean }, curr: [Object, Object]) => {
        return {item: curr[0], isReplay: acc.isReplay && curr[0] !== curr[1]};
      }, {isReplay: true}
    ).subscribe(...);
    

    【讨论】:

    • 先生。米勒您认为@Voskanyan David 的答案更好吗?看起来更简单
    • 您问题的措辞是“表明 ReplaySubject (暂时)为空/没有事件的最佳方式”。 @Voskanyan David 的回答会告诉您 ReplaySubject 何时完成(永久没有事件)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多