在 AngularFire 中使用 forkJoin 运行 多个并发查询
Using forkJoin to run multiple concurrent queries with AngularFire
问题
我正在使用 AngularFire2 并且想要 return 与两个或更多联系人姓名关联的数据。
例如,在我的实时数据库中查询 contactNames Steve 和 Brandon:
permits: {
1: {
permit: '12345',
contactName: 'Steve'
},
2: {
permit: '45678',
contactName: 'Brandon'
},
3: {
permit: '78910',
contactName: 'Kevin'
},
4: {
permit: '54321',
contactName: 'Steve'
},
}
会return
1: {
permit: '12345',
contactName: 'Steve'
},
2: {
permit: '45678',
contactName: 'Brandon'
},
4: {
permit: '54321',
contactName: 'Steve'
},
我的解决方案尝试
我正在使用 map 循环遍历并将可观察对象存储在数组中
contactNamesFilter: string[] = ['Steve', 'Brandon'];
const requests = this.contactNamesFilter
.map(contactName => this.permitBrowserService.getData(contactName));
和 forkJoin 将它们全部合并为一个可观察对象。 (我使用的是 RxJS v6.6.3)
forkJoin(requests).subscribe(console.log);
问题是订阅 forkJoin observable 并没有 return 任何东西。看起来代码已经死了,而不是 运行。我知道 forkJoin 不会 return 任何东西,直到所有 observables 都有 returned 东西。我怀疑这与 permitBrowserService.getData() observable 在技术上是相同的有关。
我做错了什么?有没有更好的方法来解决这个问题?
其他疑难解答
我尝试明确地写出具有相同结果的可观察源:
forkJoin({
sourceOne: this.permitBrowserService.getData('Steve'),
sourceTwo: this.permitBrowserService.getData('Brandon'),
}).subscribe(console.log);
备份
我正在使用 AngularFire2 查询许可列表:
export class PermitBrowserService {
permitData$: Observable<AngularFireAction<DataSnapshot>[]>;
contactName$: BehaviorSubject<string|null>;
constructor(
public db: AngularFireDatabase,
) {
this.contactName$ = new BehaviorSubject(null);
this.permitData$ = this.contactName$.pipe(
switchMap(contactName =>
db.list('/permits', ref =>
contactName ? ref.orderByChild('contactName').equalTo(contactName) : ref
).snapshotChanges()
)
);
}
getData(contactNameFilter?: string | null): Observable<WellPermit[]> {
if (contactNameFilter) {
this.contactName$.next(contactNameFilter);
}
return this.permitData$.pipe(
map(changes => {
return changes.map(c => {
const data = c.payload.val();
const id = c.key;
return { id, ...data };
})
})
);
}
因为你的 this.permitData$
(permitBrowserService.getData()) 永远不会完成,forkJoin 永远不会发出任何东西。所以使用 combineLatest,它会在每次 this.permitData$
发出时发出。
combineLatest({
sourceOne: this.permitBrowserService.getData('Steve'),
sourceTwo: this.permitBrowserService.getData('Brandon'),
}).subscribe(console.log);
或
const requests = this.contactNamesFilter
.map(contactName => this.permitBrowserService.getData(contactName));
combineLatest([...requests]).subscribe(console.log);
Combines multiple Observables to create an Observable whose values are
calculated from the latest values of each of its input Observables.
Accepts an Array of ObservableInput or a dictionary Object of
ObservableInput and returns an Observable that emits either an array
of values in the exact same order as the passed array, or a dictionary
of values in the same shape as the passed dictionary.
问题
我正在使用 AngularFire2 并且想要 return 与两个或更多联系人姓名关联的数据。
例如,在我的实时数据库中查询 contactNames Steve 和 Brandon:
permits: {
1: {
permit: '12345',
contactName: 'Steve'
},
2: {
permit: '45678',
contactName: 'Brandon'
},
3: {
permit: '78910',
contactName: 'Kevin'
},
4: {
permit: '54321',
contactName: 'Steve'
},
}
会return
1: {
permit: '12345',
contactName: 'Steve'
},
2: {
permit: '45678',
contactName: 'Brandon'
},
4: {
permit: '54321',
contactName: 'Steve'
},
我的解决方案尝试
我正在使用 map 循环遍历并将可观察对象存储在数组中
contactNamesFilter: string[] = ['Steve', 'Brandon'];
const requests = this.contactNamesFilter
.map(contactName => this.permitBrowserService.getData(contactName));
和 forkJoin 将它们全部合并为一个可观察对象。 (我使用的是 RxJS v6.6.3)
forkJoin(requests).subscribe(console.log);
问题是订阅 forkJoin observable 并没有 return 任何东西。看起来代码已经死了,而不是 运行。我知道 forkJoin 不会 return 任何东西,直到所有 observables 都有 returned 东西。我怀疑这与 permitBrowserService.getData() observable 在技术上是相同的有关。
我做错了什么?有没有更好的方法来解决这个问题?
其他疑难解答
我尝试明确地写出具有相同结果的可观察源:
forkJoin({
sourceOne: this.permitBrowserService.getData('Steve'),
sourceTwo: this.permitBrowserService.getData('Brandon'),
}).subscribe(console.log);
备份
我正在使用 AngularFire2 查询许可列表:
export class PermitBrowserService {
permitData$: Observable<AngularFireAction<DataSnapshot>[]>;
contactName$: BehaviorSubject<string|null>;
constructor(
public db: AngularFireDatabase,
) {
this.contactName$ = new BehaviorSubject(null);
this.permitData$ = this.contactName$.pipe(
switchMap(contactName =>
db.list('/permits', ref =>
contactName ? ref.orderByChild('contactName').equalTo(contactName) : ref
).snapshotChanges()
)
);
}
getData(contactNameFilter?: string | null): Observable<WellPermit[]> {
if (contactNameFilter) {
this.contactName$.next(contactNameFilter);
}
return this.permitData$.pipe(
map(changes => {
return changes.map(c => {
const data = c.payload.val();
const id = c.key;
return { id, ...data };
})
})
);
}
因为你的 this.permitData$
(permitBrowserService.getData()) 永远不会完成,forkJoin 永远不会发出任何东西。所以使用 combineLatest,它会在每次 this.permitData$
发出时发出。
combineLatest({
sourceOne: this.permitBrowserService.getData('Steve'),
sourceTwo: this.permitBrowserService.getData('Brandon'),
}).subscribe(console.log);
或
const requests = this.contactNamesFilter
.map(contactName => this.permitBrowserService.getData(contactName));
combineLatest([...requests]).subscribe(console.log);
Combines multiple Observables to create an Observable whose values are calculated from the latest values of each of its input Observables.
Accepts an Array of ObservableInput or a dictionary Object of ObservableInput and returns an Observable that emits either an array of values in the exact same order as the passed array, or a dictionary of values in the same shape as the passed dictionary.