Switchmap运算符没有迭代从Observable返回的值

wyyhbhjk  于 2022-10-24  发布在  Angular
关注(0)|答案(1)|浏览(163)

我有2个防火基地的原材料和库存清单。库存列表包含具有原材料关键字的对象。我用那把钥匙去取原材料。我正在获取所有的库存列表,然后当我迭代列表中的每个对象以连接原材料时,问题是可观测对象只返回第一个对象。这意味着,它不会遍历所有列表。这是我的代码

rawMaterialsStocksRef: AngularFireList<any>;
  rawMaterialStockRef: AngularFireObject<any>;

  private dbPathStock = '/raw_material_stock';

  constructor(
    private db: AngularFireDatabase,
    private rawMaterialService: RawMaterialsManagementService
  ) {
    this.rawMaterialsStocksRef = db.list(this.dbPathStock);
  }

getRawMaterialStockList() {

   const rawData = this.rawMaterialsStocksRef.valueChanges().pipe(
      map(rawMaterialsStocks =>
        rawMaterialsStocks.map(stock => ({
         ...stock
        }))
      ),
      switchMap(stockArr => from(stockArr)), 
      // gives the following 
      // { "factoryKey": "34""quantity": "34", "rawMaterialKey": "-NDNPe47CDTbjmwGgW_3"}
      // { "factoryKey": "20", "quantity": "20", "rawMaterialKey": "-NDIjiVqKP-lLwJGwmic"}
      switchMap(stock =>
        // this service i use to fetch each raw material based on its key
        this.rawMaterialService.getRawMaterial(stock.rawMaterialKey).valueChanges()
          .pipe(
            map(rawMaterial => {
              return { ...stock, ...rawMaterial }
            })
          )
      ),
    );

   rawData.subscribe()
}

这是我得到的结果

{
    "factoryKey": "20",
    "quantity": "20",
    "rawMaterialKey": "-NDIjiVqKP-lLwJGwmic",
    "code": "KLL2311",
    "name": "Material 03"
}

如您所见,尽管数组包含多个对象,但我只成功连接了一次!
请帮帮我,我花了3天时间,什么都试过了,就是不管用!

omtl5h9j

omtl5h9j1#

SwitchMap

SwitchMap中的开关用于表示操作符的额外行为。Switch的意思是“如果前一个可观测对象处于活动状态,则丢弃它,切换到这个对象。”
连接Map的意思是“如果仍有活动的可观察对象,则将其放入队列中,以便在前面的可观察对象完成后立即运行”
MergeMap的意思是“我不在乎现在是否或有多少以前的观察体正在运行。订阅所有这些观察体,并发射任何源观察体发射的任何物质”。
将您的Switchmap更改为其他两个之一

mergeMap(stock => this.rawMaterial..........
  ........

旁白

我建议你选择一种编程风格。您的代码同时具有这两种功能

map(stock => ({
  ...stock
}))

map(rawMaterial => {
  return { ...stock, ...rawMaterial }
})

选项一:

map(stock => ({
  ...stock
}))

map(rawMaterial => ({ 
  ...stock, ...rawMaterial 
}))

选项2:

map(stock => {
  return { ...stock }
})

map(rawMaterial => {
  return { ...stock, ...rawMaterial }
})

将它们混合在同一小段代码中,会使您更难连贯地浏览代码。

更新#1

使用forkJoin并行返回结果数组。

mergeMap(stockArr => forkJoin(stockArr.map(stock =>
  this.rawMaterialService
    .getRawMaterial(stock.rawMaterialKey)
    .valueChanges()
    .pipe(
      map(rawMaterial => ({ ...stock, ...rawMaterial }))
    )
)))

相关问题