基本上,我昨天询问了重复使用来自可观察数据的数据,然后我也在其他地方询问并阅读更多内容然后我想,为什么不只是持有一个observable并用map
运算符操纵数据。
所以我只做一个HTTP请求,将observable存储到某个变量并在那里操作它。该代码有效,但我不确定我是否正确使用.publishReplay(1).refCount()
,还是应该使用connect
?或者,我是否需要其中任何一个?此外,该服务是否可能出现内存泄漏?
这是要服务的代码:
@Injectable()
export class UsersApiService {
private readonly baseUrl: string = 'https://reqres.in/api/users';
resource$: Observable<any>;
constructor(private http: HttpClient) {
this.resource$ = this.http.get<IUserDetails[]>(this.baseUrl).pipe(
tap((data) => {
console.log('"getUsers" successfully called!');
}),
map((data: any) => {
return data.data;
})
).publishReplay(1).refCount();
}
getUsers(): Observable<IUser[]> {
return this.resource$.pipe(
map((data: IUserDetails[]) => {
return <IUser[]>data.map((u) => {
return {
id: u.id,
name: `${u.first_name} ${u.last_name}`
};
});
})
);
}
getUserById(id: number): Observable<IUserDetails> {
return this.resource$.pipe(
map((data) => {
return <IUserDetails>data.find(x => x.id === id);
})
);
}
}
答案 0 :(得分:7)
我不确定我是否正确使用.publishReplay(1).refCount()
是的,你是。您也可以使用shareReplay(1)
代替。
当第一个订阅者出现时,还是应该使用connect?
refCount()
已经为您连接(并且当所有观察者都取消订阅时断开连接)。
我甚至需要这些吗
如果你想把它当作一个可观察的,是的。否则,您将一遍又一遍地查询后端。但是,你当然也可以记住最后一次发射:
private resource: Observable<IUserDetails[]>;
constructor(http: HttpClient) {
this.http.get(/* … */).subscribe(data => this.resource = data);
}
getUserById(id: number): IUserDetails {
return this.resource.find(x => x.id === id);
}
此外,该服务是否可能出现内存泄漏?
不,因为HttpClient
完成了它的返回可观察性,这意味着您的多播observable的来源已断开。
答案 1 :(得分:0)
如果您的目标是重用http调用,为什么不使用share运算符。它基本上为您在幕后处理发布和refCount。