forkJoin不能使用AngularFire2 valueChanges

时间:2017-12-13 09:58:31

标签: angular firebase rxjs angularfire2 rxjs5

请帮助我解决我遇到的问题。

我有一组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'}]

3 个答案:

答案 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至少发出一次之前不会触发;因此我们使它们全部立即发出其默认值。