首页 > 解决方案 > 是否有更有效的方式在 Typescript 的订阅中进行订阅

问题描述

我正在使用Typescript for Angular 11编写一些代码,我需要从一个 observable 获取数据,然后循环通过另一个调用来获取名称。获得名称后,我想将其附加到原始对象。

例如,我有两个 observables 和 getSelfPurchases() 返回:

{
  id: 32
  user_id: 5
  script_id: 78
  pp_id: "76SDI89768UIHUIH8976"
},
{
  id: 33
  user_id: 4
  script_id: 79
  pp_id: "78FGGF78SDF78FSD"
}

第二个,getScriptDetails(32),返回:

{
  sname: "Spell Checker"
  author: 43
  price: 20.99
}

我已经成功地实现了我想做的事情,但我觉得它是草率和低效的。我一直在阅读更多关于 RXJS 的东西,比如 switch map,但我不确定是否可以完成类似的事情。或者也许我选择的方法已经是最好的了。输入?

this.userService.getSelfPurchases().subscribe(response => { // first observable
  this.purchases = response;

  this.purchases.forEach((purchase, index) => { // loop through our results
    this.scriptService.getScriptDetails(purchase.script_id).subscribe(responseTwo => { // second observable
      if (responseTwo[0] && responseTwo[0].sname !== undefined) {
        this.purchases[index].sname = responseTwo[0].sname; // append to our original purchases object
      }
    });
  });
});

标签: angulartypescripthttprxjsobservable

解决方案


这是一个典型的案例 swichMap, forkJoin, map

  1. 首先获取列表
  2. 创建一个可观察的数组
  3. 使 forkJoin
  4. 映射初始列表添加接收到的值

在代码中

this.userService.getSelfPurchases().pipe(
   switchMap(purchases=>{
         //here you has the purchases, e.g. [{script_id:2,script_id:4}]
         //so create an array with the observables
         const obs=purchases.map(purchase=>this.scriptService.getScriptDetails(purchase.script_id))
        //using switchmap we should return an observable
        return forkJoin(obs).pipe(
            //data is an array with the response of the call for script_id:2 and script_id4
            //but we don't want return only an array with the data
            //so we use map to transform the data
            map((data:any[])=>{
               //we loop over purchases to add the properties
               //we get in data
               purchases.forEach((purchase,index)=>{
                  purchase.sname=data[index].sname
                  purchase.author=data[index].author
                  purchase.price=data[index].price
                  purchase.author=data[index].author
               }
               //finally return purchases
               return purchases
            })
        )
   })
)

推荐阅读