叉加入两个firebase观察 [英] Fork join two firebase observables

查看:113
本文介绍了叉加入两个firebase观察的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用angular2fire。我在询问,试图从一个城市获得所有的旅行。

  getAllTours(cityId){
return this.af.database.list(`/ cities / $ {cityId} (tours):any => {
tours.map((tour:any)=> {
tour.tour = this.af.database .object(`/ tours / $ {tour。$ key} / tours`)
});
return tours;
})
}

如果我console.log游览对象,我得到一个FirebaseObjectObservable数组。

我必须遍历所有FirebaseObjectObservable,才能获取实际的数据。



我想知道是否可以forkJoin所有observables并获得输出作为一个单一的订阅功能的数组。

这是一个正确的方法吗?

我知道我可以在所有观察者数组上做一个异步管道,但是我想获取控制器内的数据,然后在显示在查看,所以异步管道真的不是我最好的解决方案。

解决方案

可以使用 forkJoin 来获取内部观察:

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

//游览数组将被映射到可观察值
// so so mergeMap is used。

return Observable.forkJoin(

//将游览映射到
//的可观察数组需要注意的是forkJoin需要可观察对象
//才能完成,所以首先使用

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

//使用forkJoin的结果选择器来匹配结果
// va与旅游色彩。

(... values)=> ((tour,index)=> {tour.tour = values [index];}); {
tours.forEach
回程旅游;
}
);
});



$ b $ p $是否使用 forkJoin getAllTours 返回的可观察元素,直到所有的内部可观测物都已经完成 - 也就是说,直到每个城市的旅行都被抬起来之后才会发出一个值。如果 / cities / $ {cityId} / tours 中的信息可能会显示在 / tours / $ {tour。$ key} / tours 被查找,您将无法显示它。同样,当结果到达时,您将无法显示城市的旅程。



使用 forkJoin 实现起来比较简单,但是可能会让UI感觉变慢。 (但是,对用户界面的零碎更新可能是你不想要的东西。)



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

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

tours.forEach((tour)=> {

//使用您的函数, tour是一个可观察对象,所以map
//可以用来处理这些值。

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

//用这个值做一些处理
})

//如果你对动态更新不感兴趣,你可以
// call首先,

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

您可以使用 async 该模板,它会收到您的处理游览。


I am using angular2fire. I am querying and trying to get all the tours from a city.

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

If i console.log the tour object, i get a array of "FirebaseObjectObservable".

I have to loop through all the FirebaseObjectObservable, to get the actual data.

I was wondering if i could forkJoin all the observables and get the output as an array with a single subscribe function.

Is this a right approach.

I know i can do an async pipe on all the observers array, but i would like to get the data inside the controller and then do some processing before its shown in the view, so async pipe is really not the best solution for me.

解决方案

Yes, forkJoin could be used to get the data for the inner observables:

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

Whether or not using forkJoin is the right approach will depend upon your requirements.

With the above code, the observable returned by getAllTours will not emit a value until all of the inner observables have completed - that is, until each of the city's tours have been looked up. That could affect perceived performance - if there is information in /cities/${cityId}/tours that could be shown before the information in /tours/${tour.$key}/tours is looked up, you won't be able to show it. Similarly, you won't be able to show the city's tours as the results arrive.

Using forkJoin makes dealing with the implementation simpler, but it might make the UI feel slower. (However, piecemeal updates to the UI might be something that you do not want.)

Note that if you do need to do some processing on each of the city's tours before it is shown in the view, you might be able to perform said processing on the observables in the code in your question. For example, using your getAllTours function:

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

You could then use the async pipe in the template and it would receive your processed tours.

这篇关于叉加入两个firebase观察的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆