请帮助我解决我遇到的问题。
我有一组Firebase对象密钥
const keys = ['-Kx9pqoMWlJLbKLQcAkP', '-Kx9pqoOYlDHTJ64Was5']
我尝试做的是使用forkJoin
将所有Firebase对象放在一个流中。这就是我所拥有的:
const obj1 = this.fbService.getObj(keys[0]);
const obj2 = this.fbService.getObj(keys[1]);
forkJoin([obj1, obj2])
.subscribe(res => {
console.log(res); // <-- this never happens
};
fbService方法是:
getObj(key): Observable<MyObj> {
return this.fb.object(`/path/to/obj/${key}`).valueChanges();
}
我认为此getObj
方法与forkJoin
无法正常工作,可能是因为valueChanges
,我是否正确使用它?
然而:
getObj
可以很好地获取单个Firebase对象,例如:
this.fbService.getObj(keys[0])
.subsribe(res => console.log(res))// <-- works
forkJoin
可以处理简单的HTTP请求,例如
const r1 = this.http.get('https://swapi.co/api/people/1');
forkJoin([r1])
.subscribe(res => {
console.log(res); // <-- works
};
那么,我做错了什么? 我的目标是从键数组中获取对象数组:
['-Kx9pqoMWlJLbKLQcAkP', '-Kx9pqoOYlDHTJ64Was5'] => [{prop:'val'},{prop:'val2'}]
答案 0 :(得分:5)
forkJoin
运算符要求所有源Observable至少发出一个项并完成。
我对firebase了解不多,但我怀疑valueChanges
永远不会完成,所以forkJoin
永远不会发出任何事情。解决此问题的一种方法是使用take(1)
始终完成链。
forkJoin(obj1.take(1), obj2.take(1)).subscribe(res => console.log(res);
在您的情况下,最好使用zip()
运算符,只需要所有源Observable发出相同数量的项。但是请确保取消订阅,因为在源Observables完成之前它不会完成。
答案 1 :(得分:1)
@martin提供了正确的答案,但是代码示例需要更新为新的RxJS语法:
forkJoin(obj1.pipe(take(1)), obj2.pipe(take(1))).subscribe(res => console.log(res));
答案 2 :(得分:0)
尝试使用startWith
运算符
getObj(key): Observable<MyObj> {
return this.fb.object(`/path/to/obj/${key}`)
.valueChanges.pipe(starWith(value)); // value can be default obj to trigger stream
}
可能是因为
valueChanges
在您手动触发流之前不会开始发出,因此forkJoin
在所有源Observable至少发出一次之前不会触发;因此我们使它们全部立即发出其默认值。