[英]How to combine Subjects and Observables with Angular rxjs
我有以下兩個訂閱:
this.service1.source1.subscribe(countries => {
this.filteredData = [];
countries.forEach(country => {
this.filteredData = this.data.filter(user => {
return user.country == country;
});
});
});
this.service2.source2.subscribe(companies => {
companies.forEach(company => {
this.filteredData = [];
this.filteredData = this.data.filter(user => {
return user.company == company;
});
});
});
其中source1和source2是BehaviorSubject
並且這兩個事件都被subscribe
捕獲。
我想結合兩個訂閱,因為我想根據subscribe
返回的結果過濾數據
我試過forkJoin
和zip
zip([this.service1.source1, this.service1.source2]).subscribe(results => {
console.log('zip results:', results);
});
forkJoin([this.service1.source1, this.service1.source2]).subscribe(results => {
console.log('forkJoin results:', results);
});
但是對於那些(zip和forkJoin),我注意到我甚至沒有在控制台上得到任何東西,就像發出事件時subscribe
沒有被執行一樣。
如何將兩個來源的結果合並為一個訂閱?
語法錯了。 forkJoin
和zip
接受Observables作為參數。 不是一個Observables數組。 從通話中刪除[]
你應該沒事。
嘗試這個:
zip(this.service1.source1, this.service1.source2).subscribe(results => {
console.log('zip results:', results);
});
forkJoin(this.service1.source1, this.service1.source2).subscribe(results => {
console.log('forkJoin results:', results);
});
forkJoin
可能不適合您的用例,因為當所有可觀察對象完成時,它會從每個用例中發出最后一個值。
zip
也可能無法提供所需的行為,因為它等待所有輸入流都發出它們的第n個值,並且只要滿足此條件,它就會組合所有這些第n個值並發出第n個組合值。
所以在任何一種情況下,在兩個可觀測量都有排放之前,你不會得到排放。 因為this.service1.source1
和this.service1.source2
是使用zip
BehaviorSubject保證初始發射。 但是后來的排放只有在兩個可觀察物都發射時才會發生。
我建議在任何輸入流發出值時使用combineLatest beacuse ,它結合了每個輸入流發出的最新值。
combineLatest(this.service1.source1, this.service1.source2).subscribe(results => {
console.log('combineLatest results:', results);
});
因為this.service1.source1
和this.service1.source2
是BehaviorSubject ,所以:
Subject的變體,需要初始值並在訂閱時發出其當前值。
保證您在訂閱它時以及任何可觀察的任何值都會發出值時獲得一個emmission。
正如@ysf在上面指出的那樣,如果你想用兩種結果在發射時過濾本地數據,你應該選擇combineLatest
。
另外,我建議您在每個服務中創建一個變量作為BehaviorSubject
的Observable實例。 喜歡:
// at Service1.service.ts
export class Service1Service {
// Do not expose Subject directly.
private source1 = new BehaviorSubject<YourDataType[]>(YourInitialValue);
private source2 = new BehaviorSubject<YourDataType[]>(YourInitialValue);
source1$: Observable<YourDataType[]>;
source2$: Observable<YourDataType[]>;
constructor() {
// Create an Observable instance for your sake and open it to the public.
this.source1$ = this.source1.asObservable();
this.source2$ = this.source2.asObservable();
}
}
// at wherever you subscribe
combineLatest(this.service1.source1$, this.service1.source2$).pipe(
filter(([res1, res2]: YourDataType[]) => {
// Filter your data with res1, res2
})
).subscribe();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.