哪个rxjs / Observable函数用于将递归的Observable分页数据合并为单个流或数组

时间:2018-02-26 15:46:57

标签: observable rxjs5

我正在使用ajax使用rxjs / Observable来获取大量数据。服务器输出页面中的数据。我正在尝试使用递增的页码进行递归的ajax调用。目前我的代码在没有分页时工作。但  我无法进行分页工作。

我用我的用例创建了一个plunker模拟数据和服务来重新创建场景。

感谢任何帮助或指导。感谢

export class App implements OnInit {        
    //mock db
    db:{[Id:string]:{data:number[],links:{next:number}}};

    uiData: number[];

    constructor() {
        this.name = `Angular! v${VERSION.full}`;

       //populate mock db with some data
       this.db = {
           '1_1': {data: [1,2,3,4,5], links: {next: null}},
           '2_1': {data: [1,2,3,4,5], links: {next: 2}},
           '2_2': {data: [6,7,8,9,10], links: {next: 3}},
           '2_3': {data: [11,12,13,14], links: {next: null}}
       };
    }

    /**
     * Mock db layer with API
     */
    private queryMasterData(key: string, page: number=1) {
       return Observable.of(this.db[`${key}_${page}`]);
    }

    /** Will be a angular service layer */
    private getPaged(key: string, page: number) {
        return this.queryMasterData(key, page).map(response => {
            if (response && response.links && response.links.next) {
                //? What Observable method to call? 
                return Observable.concat(Observable.of(response.data), 
                       this.getPaged(key, response.links.next).map(data => data));
            }

            if(!!response) {
                return response.data;
            }

            return [];
         });
     }

     /** Will be a angular service layer. UI can onlu call this */
     public getAll(key: string) {
         return this.getPaged(key, 1);
     }

     /** This is a component layer call */
     populateUI(key:string) {
         this.getAll(key).subscribe(data=>{
         console.log('populateUI', data);
         this.uiData = data;
     });
  }

  ngOnInit() {

  }  
}

1 个答案:

答案 0 :(得分:1)

Multiple ways to solve this, but the most important part is remembering to keep the dual responses you are dealing with the same. Solution that works with your plunker:

private getPaged(key: string, page: number) {
  return this.queryMasterData(key, page).flatMap(response => {
    if (response && response.links && response.links.next) {
        return Observable.forkJoin(Observable.of(response.data), this.getPaged(key, response.links.next).map(data => data)).map(x => {
          let combined = x[0].concat(x[1]);
          return combined
      });
    }                    
  
    if(!!response) {
      return Observable.of(response.data);
    }     
    
    return [];
  });
}