叉加入两个firebase观察 [英] Fork join two firebase observables
问题描述
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 $ c $使用上面的代码,由 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屋!