[英]Updating count items with behaviorsubject cross side component communication
[英]Side effects with BehaviorSubject and 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}`, {}, { headers: headers })
.pipe(
catchError(err => throwError(err)),
concatMap(() => this.profileService.profiles$),
map(profiles => {
const selectedProfile = profiles.findIndex(profile => profile.id === profileId);
profiles[selectedProfile].canEdit = true;
return profiles;
})
);
}
這個邏輯就像購物車邏輯。 我將產品添加到其中一個配置文件,以避免再次調用 api (getUserProfiles) 我修改配置文件 $ stream 並添加我想要的屬性(在本例中為 canEdit)但是當我從購物車中刪除產品時問題出現了並從 getUserProfiles() 恢復數據我知道,當我將 concatMap 與profiles$ 一起使用時,即使我沒有調用 function,我也會對 addProduct() 產生副作用,我的問題是......
為什么它繼續執行
map(profiles => {
const selectedProfile = profiles.findIndex(profile => profile.id === profileId);
profiles[selectedProfile].canEdit = true;
return profiles;
})
使用我過去作為參數傳遞的舊 profileId,即使我沒有調用 addProduct() function,如何避免這種情況?
將 observables 想象成一個水龍頭,一旦你訂閱它,水龍頭就永遠不會關閉。 只要有水,水就會一直流動。 只有當您取消訂閱它(或任何其他終止它的運營商)時,水龍頭才會關閉。
因此,在您執行addProfile()
的那一刻,即使只是一次,它的 observable 將永遠打開,並且只要有數據(水)排放,即使您不調用 function,數據的排放仍將繼續addProfile()
不再-> 而且,如果您調用 function 兩次,您實際上有兩個訂閱,即兩個水管和水龍頭; 這是大多數開發人員沒有注意的事情。
因此,當您第一次調用addProfile()
時,並且由於您從未取消訂閱它,您實際上切換到收聽profiles$
感謝
concatMap(() => this.profileService.profiles$),
, 你的 stream 的數據實際上變成了監聽那個 BehaviourSubject 的變化,這就解釋了即使你不再調用addProfile()
了,但是因為你更新了你的profiles$
,排放量仍然是 go 通過,並且數據流將流過管道,然后將有效地執行下一個 pipe 運算符:
map(profiles => {
const selectedProfile = profiles.findIndex(profile => profile.id === profileId);
profiles[selectedProfile].canEdit = true;
return profiles;
})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.