[英]How to map over an observed array to combine multiple obervables latest values
I am piping into an observable, that streams an array of let's say food.我正在输入一个可观察的数据,它会传输一系列食物。 I need to get the latest cook, the latest kitchen, and the latest knife used to prepare each of these food items.我需要最新的厨师、最新的厨房和用于准备这些食物的最新刀。 These three values are all values got by an observable like getCookById(food.cook.id).这三个值都是像 getCookById(food.cook.id) 这样的 observable 获得的值。 How could i map it so:我怎么能这样:
{
foodItem,
cook,
kitchen,
knife
}
Currently, I get an array of empty items doing it like so:目前,我得到一组空项目,如下所示:
const foodObservable = new Subject(); foodObservable.pipe( map(foodItems => { return foodItems.map((foodItem: any)=>{ const cookObservable = new Subject(); const kitchenObservable = new Subject(); const knifeObservable = new Subject(); combineLatest(cookObservable, kitchenObservable, knifeObservable).subscribe(([cook, kitchen, knife]) => { return { foodItem, cook, kitchen, knife }; }); }) }) ).subscribe(foodPreparationArray=>{ console.log(foodPreparationArray) // array of empty values:( })
Based on your condition and your comment, I'd suggest the following changes根据您的情况和您的评论,我建议进行以下更改
You'd need to use a higher order mapping operator like switchMap
to map from one observable to another.您需要使用更高阶的映射运算符,例如switchMap
到 map 从一个可观察到另一个。 map
operator is used to transform the emitted data. map
算子用于转换发射的数据。
Using Firebase get()
instead of valueChanges()
would be a better fit.使用 Firebase get()
而不是valueChanges()
会更合适。 I assume you need the value at the moment and do not need to observe any changes to the property.我假设您目前需要该值,并且不需要观察该属性的任何更改。 See here for more info.请参阅此处了解更多信息。
Using get()
instead of valueChanges()
provides us with us observables that completes instead of streaming.使用get()
而不是valueChanges()
为我们提供了完成而不是流式传输的 observables。 So you could replace the combineLatest
with forkJoin
.所以你可以用combineLatest
替换forkJoin
。
You'd need two forkJoin
s.你需要两个forkJoin
。 First forkJoin
is to trigger requests for each element of the foodItems
array and second forkJoin
is to trigger requests for cook
, knife
, and kitchen
simultaneously.第一个forkJoin
是触发对foodItems
数组的每个元素的请求,第二个forkJoin
是同时触发对cook
、 knife
和kitchen
的请求。
Finally you could use the map
operator to combining everything.最后,您可以使用map
运算符来组合所有内容。
Try the following尝试以下
foodObservable.pipe(
switchMap((foodItems: any) => // <-- RxJS `switchMap` operator
forkJoin(
foodItems.map((foodItem: any) => // <-- JS `Array#map` function
forkJoin({
cook: db.collection('cook').doc(foodItem.cookId).get(),
kitchen: db.collection('kitchen').doc(foodItem.kitchenId).get(),
knife: db.collection('knife').doc(foodItem.knifeId).get()
}).pipe(
map(({cook, kitchen, knife}) => ({ // <-- RxJS `map` operator
...foodItem, // <-- spread operator
cook: cook,
kitchen: kitchen,
knife: knife
)})
)
)
)
)
).subscribe({
next: (foodPreparationArray: any) => {
console.log(foodPreparationArray);
},
error: (error: any) => {
// handle error
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.