Angular 8 个带有映射的子请求的 http 子请求

Angular 8 http subrequests for children with mapping

我必须在对 getTree() 的一次调用中执行以下请求,该调用必须 return 一个 Observable<TreeNode>.

我对嵌套子地图请求有问题

    getTree(): Observable<TreeNode> {
        return this.getTransactionId().pipe(
            concatMap(trx => {return this.getRootNode(trx, 50);}),
            tap(result => {this.transactionClose().subscribe()})
        ) as Observable<TreeNode>;
    }

    getRootNode(trx: number, nodeId: number): Observable<TreeNode> {
        this.log('fetching root node '+ nodeId);
        var urlRootNode = config['apiUrl'] + `/dataview/perspective/get_root_nodes/trx=${trx}&id=${nodeId}`;
        return this.http.get<TreeNode>(urlRootNode).pipe(
            map(data => { 
                this.log('got root node data ' + data);
                let node = data[0]; 
                node.children = node.children.map(id => {
                    return this.getNodeChild(trx, id).subscribe();
                    // this is where I need help, because
                    // right now, the subscriber of getTree gets notified before the children are loaded
                });


                return node;
            }),
            catchError(this.handleError<TreeNode>('getRootNode'))
        )
    }

    getNodeChild(trx: number, nodeId: number): Observable<TreeNode> {
        this.log('fetching node '+ nodeId);
        var urlNode = config['apiUrl'] + `/dataview/node/get_children/trx=${trx}&id=${nodeId}`;
        return this.http.get<TreeNode>(urlNode).pipe(
            map(data => { 
                this.log('got node data ' + data);
                let node = data[0];                 

                return node;
            }),
            catchError(this.handleError<TreeNode>('getNodeChild'))
        )
    }

我认为可以用下一种方式进行(更改:switchMap 添加,return 来自压缩和映射源)

getRootNode(trx: number, nodeId: number): Observable<TreeNode> {
    this.log('fetching root node '+ nodeId);
    var urlRootNode = config['apiUrl'] + `/dataview/perspective/get_root_nodes/trx=${trx}&id=${nodeId}`;
    return this.http.get<TreeNode>(urlRootNode).pipe(
        switchMap(data => { 
            this.log('got root node data ' + data);
            let node = data[0]; 
            let children$ = zip(...node.children.map(id => {
                return this.getNodeChild(trx, id)
            }));


            return children$.pipe(map(children => node.children = children), map(()=> node));
        }),
        catchError(this.handleError<TreeNode>('getRootNode'))
    )
}