我正在使用一个库,该库使用非常常见的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的不同组合的问题,但没有看到关于这一特定问题的问题
答案 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)
)。