我用的是安格拉尔2火焰。我正在查询并试图从一个城市得到所有的旅游。

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;
        })
}

如果我console.log这个tour对象,就会得到一个“firebaseobjectobservate”数组。
我必须循环浏览所有的firebaseobjectobservate,才能得到实际的数据。
我想知道我是否可以forkjoin所有的观察值,并获得一个带有一个subscribe函数的数组输出。
这是正确的方法吗?
我知道我可以在所有的观察者数组上做一个异步管道,但是我想在控制器中获取数据,然后在它显示在视图中之前做一些处理,所以异步管道对我来说不是最好的解决方案。

最佳答案

是的,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返回的可观测数据在所有的内部可观测数据都完成之前不会发出值,也就是说,在每个城市的旅游数据都被查找完之前。这可能会影响感知性能-如果在查找/cities/${cityId}/tours中的信息之前,/tours/${tour.$key}/tours中的信息可以显示,则您将无法显示它。同样,当结果到达时,您将无法显示城市的旅游。
使用forkJoin使处理实现变得更简单,但它可能会使ui感觉更慢。(但是,对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管道,它将接收您处理的巡更。

10-01 08:58