有什么理由在BehaviorSubject管道中使用shareReplay(1)?

时间:2019-04-29 21:04:33

标签: rxjs

我正在使用一个库,该库使用非常常见的BehaviorSubject模式公开来自服务类的数据。与实现以及我自己看到/使用过的唯一显着区别是,在pipe上加上了shareReplay(1)运算符。我不确定是否需要shareReplay。在这种情况下,shareReplay有什么作用?

// "rxjs": "^6.3.0"
this.data = new BehaviorSubject({});
this.data$ = this.data.asObservable().pipe(
   shareReplay(1) 
)

注意:我已经阅读了许多有关shareReplay的文章,并且看到了有关shareReplay和Subject的不同组合的问题,但没有看到关于这一特定问题的问题

2 个答案:

答案 0 :(得分:2)

不是在您的示例中,而是想象如果映射函数中有一些复杂的逻辑可以转换数据,那么共享重播将节省为每个订阅运行的复杂逻辑。

const { BehaviorSubject } = rxjs;
const { map, shareReplay } = rxjs.operators;

const bs$ = new BehaviorSubject('initial value');

const obs$ = bs$.pipe(
  map(val => {
    console.log('mapping');
    return 'mapped value';
  }),
  shareReplay()
);

obs$.subscribe(val => { console.log(val); });

obs$.subscribe(val => { console.log(val); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.1/rxjs.umd.min.js"></script>

不进行共享比较,地图就会出现两次。

const { BehaviorSubject } = rxjs;
const { map } = rxjs.operators;

const bs$ = new BehaviorSubject('initial value');

const obs$ = bs$.pipe(
  map(val => {
    console.log('mapping');
    return 'mapped value';
  })
);

obs$.subscribe(val => { console.log(val); });

obs$.subscribe(val => { console.log(val); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.1/rxjs.umd.min.js"></script>

答案 1 :(得分:0)

使用这种模式(使用shareReplay(1)),服务在发送BehaviorSubject的最后一个值时会使用BehaviorSubject的next()函数保护自己免受用户攻击(事实并非如此)没有shareReplay(1))。