简体   繁体   English

如何在观察到的阵列上 map 以组合多个可观察的最新值

[英]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:我怎么能这样:

  • I'm waiting for the array of food我在等待食物的排列
  • When i receive it, I map on every food item to:当我收到它时,我会在每个食品上 map:
    • get latest cook, kitchen and knife that are all from Observables (combineLatest?)从 Observables 获取最新的厨师、厨房和刀具(combineLatest?)
    • combine all of that on an object like将所有这些结合在 object 上,例如
{
   foodItem,
   cook,
   kitchen,
   knife
}
  • return the array of all these transformed items返回所有这些转换项的数组

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根据您的情况和您的评论,我建议进行以下更改

  1. 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算子用于转换发射的数据。

  2. 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.请参阅此处了解更多信息。

  3. 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

  4. 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是同时触发对cookknifekitchen的请求。

  5. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM