如何解决BehaviorSubject 和 concatMap 的副作用
这是我第一次尝试使用 BehaviorSubject、异步管道和 concatMap,所以我在更新 DOM 中的数据时遇到了一些问题。
我有:
private profilesstore = new BehaviorSubject<any>(null);
profiles$ = this.profilesstore.asObservable();
getUserProfiles(): Observable<Profile[]> {
const headers = this.authService.getHeaders();
return this.http.get<any>(`${API_URL}/profile`,{ headers: headers })
.pipe(
catchError(err => throwError(err)),tap(res => this.profilesstore.next(res)),shareReplay()
);
}
然后
addProduct(profileId: any) {
const headers = this.authService.getHeaders();
return this.http.post<any>(`${apiUrl}/products/${profileId}`,{},concatMap(() => this.profileService.profiles$),map(profiles => {
const selectedProfile = profiles.findindex(profile => profile.id === profileId);
profiles[selectedProfile].canEdit = true;
return profiles;
})
);
}
这个逻辑就像购物车逻辑。我将产品添加到其中一个配置文件中,因此为了避免再次调用 api (getUserProfiles),我修改了配置文件 $ 流并添加了我想要的属性(在本例中为 canEdit),但是当我从购物车中删除产品时出现问题并从 getUserProfiles() 恢复数据我明白,当我将 concatMap 与 profiles$ 一起使用时,即使我没有调用该函数,我也会对 addProduct() 产生副作用,我的问题是...
为什么它会继续执行
map(profiles => {
const selectedProfile = profiles.findindex(profile => profile.id === profileId);
profiles[selectedProfile].canEdit = true;
return profiles;
})
使用我过去作为参数传递的旧 profileId,即使我没有调用 addProduct() 函数以及如何避免这种情况?
解决方法
将 observables 想象成一个水龙头,一旦你订阅它,水龙头就永远不会关闭。只要有水,水就会一直流动。只有当您取消订阅它(或任何其他终止它的运营商)时,水龙头才会关闭。
所以当你做一个 addProfile()
的那一刻,即使只是一次,它的 observable 是永远打开的,只要有数据(水)的排放,数据的排放仍然会继续,即使您不再调用函数 addProfile()
-> 并且,如果您调用该函数两次,您实际上有两个订阅,即两个水管和水龙头;这是大多数开发者没有注意到的。
因此,当您第一次拨打 addProfile()
并且您从未取消订阅时,您实际上转而收听 profiles$
多亏了
concatMap(() => this.profileService.profiles$),
,你的数据流实际上变成了监听那个 BehaviourSubject 的变化,这就解释了即使你不再调用 addProfile()
,但是因为你更新了你的 profiles$
,排放仍然存在通过,数据流将流经管道,然后将有效地执行下一个管道操作:
map(profiles => {
const selectedProfile = profiles.findIndex(profile => profile.id === profileId);
profiles[selectedProfile].canEdit = true;
return profiles;
})
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。