Angular 使用可观察的';s获取多个项目的数据并将其作为单个映射返回(2)

Angular 使用可观察的';s获取多个项目的数据并将其作为单个映射返回(2),angular,observable,ngrx,ngrx-store,Angular,Observable,Ngrx,Ngrx Store,我有一个ID数组,对于每个ID,我想检查它的数据是否存储在本地缓存中(如果是,则获取它)或不存储(从服务器获取它)。 在这个过程的最后,我想得到一个地图,它保存了所有的ID及其解析的数据 到目前为止,我所做的每一件事都不符合我的要求。。 我能做的最接近的事情是: return this.userGroups$ .switchMap(userGroupsSet => Observable.from(userGroupsSet[GROUP_LIST_TYPE[groupType]])

我有一个ID数组,对于每个ID,我想检查它的数据是否存储在本地缓存中(如果是,则获取它)或不存储(从服务器获取它)。 在这个过程的最后,我想得到一个地图,它保存了所有的ID及其解析的数据

到目前为止,我所做的每一件事都不符合我的要求。。 我能做的最接近的事情是:

return this.userGroups$
  .switchMap(userGroupsSet => Observable.from(userGroupsSet[GROUP_LIST_TYPE[groupType]])
    .mergeMap(groupID => Observable.of(this.getGroupByID(<string>groupID, groupType)
      .map(groupData => {
        return {[<string>groupID]: groupData}
      })
      .catch(e => Observable.empty())))
    .combineAll()
    .map(groupsArray => {
      let groupsMap: Map<string, IGroupData> = new Map();
      for (let index in groupsArray) {
        let groupID = Object.keys(groupsArray[index])[0];
        groupsMap.set(groupID, groupsArray[index][groupID])
      }
      return groupsMap;
    })
  )


 getGroupByID(groupID: string, groupType: GROUP_LIST_TYPE): Observable<any> {
    return this.userGroups$
      .switchMap(userGroups => {
        if (userGroups['groupsData'].has(groupID))
          return Observable.of(userGroups['groupsData'].get(groupID));
        else
          return this.fetchSingleGroupData(groupID, groupType)
            .map(groupData => groupData)
            .catch(e => Observable.throw(e)
            )
      })
  }
  private fetchSingleGroupData(groupID: string, groupListType: GROUP_LIST_TYPE): Observable<any> {
    return this.http.get(URLS.AB_STATIC + "groups/" + groupID + ".json", false)
      .do(groupData => {
        this.userGroups$.dispatch({
          type: GROUPS_ACTIONS.CACHED_GROUP_DATA_FETCHED,
          payload: {
            groupID: groupID,
            groupData: groupData.json()
          }
        });
      })
      .map(res => res.json())
      .catch(e => {
        if (groupListType != null)
          this.userGroups$.dispatch({
            type: GROUPS_ACTIONS.REMOVE_ID_FROM_LIST,
            payload: {
              groupID: groupID,
              groupList: groupListType
            }
          });
        return Observable.throw(e)
      })
  };
返回this.userGroups$
.switchMap(userGroupsSet=>Observable.from(userGroupsSet[GROUP\u LIST\u TYPE[groupType]]))
.mergeMap(groupID=>Observable.of(this.getGroupByID(groupID,groupType))
.map(groupData=>{
返回{[groupID]:groupData}
})
.catch(e=>Observable.empty())
.combineAll()
.map(groupsArray=>{
让groupsMap:Map=newmap();
for(让组中的索引为数组){
设groupID=Object.keys(groupsArray[index])[0];
groupsMap.set(groupID,groupsArray[index][groupID])
}
返回组映射;
})
)
getGroupByID(groupID:string,groupType:GROUP\u LIST\u TYPE):可观察{
返回此文件。userGroups$
.switchMap(用户组=>{
if(userGroups['groupsData'].has(groupID))
返回可观察的.of(userGroups['groupsData'].get(groupID));
其他的
返回此.fetchSingleGroupData(groupID,groupType)
.map(groupData=>groupData)
.catch(e=>Observable.throw(e)
)
})
}
私有fetchSingleGroupData(groupID:string,groupListType:GROUP\u LIST\u TYPE):可观察{
返回此.http.get(url.AB_STATIC+“groups/”+groupID+“.json”,false)
.do(groupData=>{
这是.userGroups$.dispatch({
类型:GROUPS\u ACTIONS.CACHED\u GROUP\u DATA\u FETCHED,
有效载荷:{
groupID:groupID,
groupData:groupData.json()
}
});
})
.map(res=>res.json())
.catch(e=>{
如果(groupListType!=null)
这是.userGroups$.dispatch({
类型:组\u操作。从\u列表中删除\u ID\u,
有效载荷:{
groupID:groupID,
groupList:groupListType
}
});
返回可观察。投掷(e)
})
};
在上面的代码中,订阅者得到一个映射,其中键是组ID,值是组数据(如果它存储在缓存中)或未解析的可观察值(如果它试图从服务器获取)。 我想得到同样的结果,我只认为所有的值都将被解析(缓存和新获取)。 值得一提的是,当缓存中有所有数据时,我得到的映射完全符合我的要求,因此问题在于获取和解析部分

我怎样才能做好呢?
此外,对本规范的任何改进都将被欣然接受

我将在这里简化问题和答案。如果你需要更多信息,请告诉我

private cache = {};

public getData(ids: string[]){
    return Observable.from(ids)
        .flatMap((id: string)=>
            this.cache[id] ?
                Observable.of({id: this.cache[id]}) :
                this.http.get(url, {id: id })
                    .map(res => { id: res.json()})
                    .do(data => Object.assign(
                        this.cache,data }
                     )
            }
        )
        .reduce(Object.assign, {});
}