Angular 分叉连接两个火基观测值

Angular 分叉连接两个火基观测值,angular,firebase,firebase-realtime-database,observable,rxjs5,Angular,Firebase,Firebase Realtime Database,Observable,Rxjs5,我用的是angular2fire。我正在查询并尝试从一个城市获得所有的旅游 getAllTours(cityId) { return this.af.database.list(`/cities/${cityId}/tours`) .map((tours): any => { tours.map((tour: any) => { tour.tour = this.af.database.object(`

我用的是angular2fire。我正在查询并尝试从一个城市获得所有的旅游

getAllTours(cityId) {
    return this.af.database.list(`/cities/${cityId}/tours`)
        .map((tours): any => {
            tours.map((tour: any) => {
                tour.tour  = this.af.database.object(`/tours/${tour.$key}/tours`)
            });
            return tours;
        })
}
如果我对tour对象进行console.log操作,就会得到一个“FirebaseObjectObservable”数组

我必须遍历所有FirebaseObjectObservable,以获得实际数据

我想知道我是否可以连接所有的可观察对象,并通过一个订阅函数将输出作为一个数组

这是正确的方法吗


我知道我可以在所有观察者阵列上执行异步管道,但我希望在控制器中获取数据,然后在其显示在视图中之前执行一些处理,因此异步管道对我来说并不是最好的解决方案

是,
forkJoin
可用于获取内部可观测数据:

getAllTours (cityId) {
    return this.af.database
        .list(`/cities/${cityId}/tours`)
        .mergeMap((tours) => {

            // The array of tours is going to be mapped to an observable,
            // so mergeMap is used.

            return Observable.forkJoin(

                // Map the tours to the array of observables that are to
                // be joined. Note that forkJoin requires the observables
                // to complete, so first is used.

                tours.map((tour) => this.af.database
                    .object(`/tours/${tour.$key}/tours`)
                    .first()
                ),

                // Use forkJoin's results selector to match up the result
                // values with the tours.

                (...values) => {
                    tours.forEach((tour, index) => { tour.tour = values[index]; });
                    return tours;
                }
            );
        });
}
使用
forkJoin
是否正确取决于您的需求

使用上述代码,
getAllTours
返回的可观测值在所有内部可观测值完成之前不会发出值,也就是说,在查询每个城市的旅游之前。这可能会影响感知性能-如果在查找
/tours/${tours.$key}/tours
中的信息之前,可以显示
/cityId}/tours
中的信息,则无法显示该信息。同样,当结果到达时,您将无法显示该城市的旅游

使用
forkJoin
使处理实现变得更简单,但可能会使UI感觉更慢。(但是,用户界面的零碎更新可能是您不想要的。)

请注意,如果您确实需要在视图中显示每个城市的游览之前对其进行一些处理,您可能能够对问题代码中的可观察对象执行上述处理。例如,使用
getAllTours
函数:

observable = getAllTours(someCityId);
observable.map((tours) => {

    tours.forEach((tour) => {

        // With your function, tour.tour is an observable, so map
        // could be used to process the values.

        tour.tour = tour.tour.map((value) => {

            // Do some processing here with the value.
        })

        // And, if you are not interested in dynamic updates, you could
        // call first.

        .first();
    });
    return tours;
});

然后,您可以在模板中使用
async
管道,它将接收您处理的巡更。

这是可行的,但我想知道我的想法是否正确,如果我有很多记录,这会不会使系统变慢?我刚刚阅读了您的评论。明天我将在答案中添加一些性能注释;很晚了。不用担心,非常感谢:)更新了答案:forkJoin是否是正确的方法。有没有一种方法可以在不使用complete/first()的情况下使用joinfork?我有类似的问题,但需要保持firsbase连接: