使用observable获取许多项的数据并将其作为单个地图返回(角度2)

时间:2017-06-08 07:02:46

标签: angular observable ngrx ngrx-store

我有一个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)
      })
  };

在上面的代码中,订户获取的密钥是组ID的映射,值是组数据(如果它存储在缓存中)或未解析的observable(如果它试图从服务器获取它) 。 我想得到同样的想法,只有所有的值都将得到解决(缓存和新提取)。 值得一提的是,当我在缓存中拥有所有数据时,我正在按照我想要的方式获取地图,因此问题在于获取和解析部分..

我该怎么做呢? 此外,我们很乐意接受对此代码的任何改进。

1 个答案:

答案 0 :(得分:0)

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

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, {});
}