Javascript 组合多个FirebaseListObservable const placeId=this.getPlaceId(); this.af.database.list(`placeUsers/${placeId}`).subscribe((userKeys)=>{ for(让index=0;index{ for(让index=0;index{ 控制台日志(设备); //接收到设备。 }); } }); } });

Javascript 组合多个FirebaseListObservable const placeId=this.getPlaceId(); this.af.database.list(`placeUsers/${placeId}`).subscribe((userKeys)=>{ for(让index=0;index{ for(让index=0;index{ 控制台日志(设备); //接收到设备。 }); } }); } });,javascript,angular,firebase,rxjs,angularfire2,Javascript,Angular,Firebase,Rxjs,Angularfire2,我目前正在尝试向跟踪某个位置的所有用户发送通知。当前的流程如下所示: 获取属于某个位置的用户(placeUsers节点) 获取属于用户的设备密钥(userDevices节点) 从deviceKeys(设备节点)获取设备 我想知道是否有办法将所有这些调用组合成一个可观察的调用 我目前的问题是,我无法知道所有这些请求何时完成。我已经研究了RxJs,这将允许我将所有这些观察值结合起来。但是我还没有找到一个很好的解决方案来解决如何使用四个节点的问题。您可以使用concatMap和forkJoin组成

我目前正在尝试向跟踪某个位置的所有用户发送通知。当前的流程如下所示:

  • 获取属于某个位置的用户(placeUsers节点)
  • 获取属于用户的设备密钥(userDevices节点)
  • 从deviceKeys(设备节点)获取设备
我想知道是否有办法将所有这些调用组合成一个可观察的调用


我目前的问题是,我无法知道所有这些请求何时完成。我已经研究了RxJs,这将允许我将所有这些观察值结合起来。但是我还没有找到一个很好的解决方案来解决如何使用四个节点的问题。

您可以使用
concatMap
forkJoin
组成一个发射设备的可观察对象。此合成的可观察对象将发射一个设备阵列,然后完成(因为
first
操作符仅用于获取第一个发射的列表或对象):

从'rxjs/Observable'导入{Observable};
导入'rxjs/add/operator/concatMap';
导入'rxjs/add/operator/first';
导入'rxjs/add/operator/forkJoin';
这个.af.database
.list(`placeUsers/${placeId}`)
.first()
.concatMap(用户密钥=>{
让observables=userKeys.map(userKey=>this.af.database
.list(`userDevices/${userKey.$key}`)
.first()
);
返回值。长度?
Observable.forkJoin(…Observable,(…List)=>[]。concat(…List)):
([])的可观测值
})
.concatMap(设备键=>{
让observables=deviceKeys.map(deviceKeys=>this.af.database
.object(`devices/${deviceKey.$key}`)
.first()
);
返回值。长度?
可观察的。forkJoin(…可观察的):
([])的可观测值
})
.subscribe(设备=>console.log(设备));
如果您想要一个不完整的观察对象,并且每当某个地点的用户或其设备发生更改时,该观察对象就会发出该地点的设备,请使用
开关映射
而不是
concatMap
组合测试
而不是
forkJoin
,并删除
第一个
操作符:

从'rxjs/Observable'导入{Observable};
导入“rxjs/add/operator/CombineTest”;
导入'rxjs/add/operator/switchMap';
这个.af.database
.list(`placeUsers/${placeId}`)
.switchMap(用户密钥=>{
让observables=userKeys.map(userKey=>this.af.database
.list(`userDevices/${userKey.$key}`)
);
返回值。长度?
可观察的。组合相关测试(…可观察的,(…列表)=>[]。concat(…列表)):
([])的可观测值
})
.switchMap(设备键=>{
让observables=deviceKeys.map(deviceKeys=>this.af.database
.object(`devices/${deviceKey.$key}`)
);
返回值。长度?
可观测。组合相关(…可观测):
([])的可观测值
})
.subscribe(设备=>console.log(设备));

如果
forkJoin
combinelateest
都可以接受一个数组参数,那么在可观测数组(
…可观测值)上使用扩展运算符有什么作用呢?@patrick没有技术原因。这只是为了尽可能直截了当地给出一个已经很长的答案。文档(如此)没有(或没有)明确说明可以传递数组,所以我不想解释这一点。此外,我似乎还记得(至少在beta测试期间)有些运算符不接受数组参数,但它们都使用扩展语法。@patrick我可以提供另一个支持扩展语法的原因,因为它刚刚咬了我一口。有些方法,如
Observable.concat
,将数组视为一个数组,并将数组的元素连接起来,因此我认为如果使用扩展语法,方法之间的关系会更加一致。
const placeId = this.getPlaceId();
        this.af.database.list(`placeUsers/${placeId}`).subscribe((userKeys) => {
            for (let index = 0; index < userKeys.length; index++) {
                let userKey = userKeys[index];

                this.af.database.list(`userDevices/${userKey.$key}`).subscribe((deviceKeys) => {

                    for (let index = 0; index < deviceKeys.length; index++) {
                        let deviceKey = deviceKeys[index];

                        this.af.database.object(`devices/${deviceKey.$key}`).subscribe((device) => {

                            console.log(device);
                            // Device received.    

                        });
                    }
                });
            }
        });