嵌套深度未知的嵌套Observable

时间:2019-06-10 03:28:01

标签: typescript rxjs

当向Sharepoint URI发送Get请求(例如http://company.com.au/teams/Telstra/_api/web/Lists/getbytitle('${listTitle}')/items)时,它返回有限数量的项目(例如30),并提供查询链接以检索接下来的30个项目,如下所示:

Sharepoint API request

我正在编写一个Angular应用程序以检索所有项目。伪代码如下:

public GetByDomainOwner(listTitle: string, domainNameOwner: string): Observable<any[]> {

    let dataToReturn = new Array<any>();

    let URI = `http://company.com.au/teams/Telstra/_api/web/Lists/getbytitle('${listTitle}')/items?$filter=DomainOwnerText eq '${domainNameOwner}'`;

    var headers: HttpHeaders = new HttpHeaders();
    headers.append('Accept', 'application/json;odata=verbose');

    while(URI !== undefined){
        const records = this.http.get(URI, {
            headers: headers,
            withCredentials: true
        });

        records.subscribe(r => {
            let data = <SharepointItem> r;

            dataToReturn.push(data.d.results);

            if(data.d.__next){
                URI = data.d.__next;
            } else{
                URI = undefined;
            }
        });
    }       

    console.log("Escaped while loop");

    return new Observable<any[]>(dataToReturn); // This is invalid obviously, but it describes how I want to make one Observable call to retrieve all data.
}

我想进行上述一个Observable调用,它将读取并订阅d.__next以检索下一个有限数量的项目

在已知嵌套深度(例如C订阅B的流,而B订阅A的流)的情况下,使用可观察的flatmap似乎很有希望。我想制作一个flatMap(可以接受其他建议),它可以重复检查并订阅更多流而无需指定深度。

1 个答案:

答案 0 :(得分:1)

正如@KiraAG所说,expand可能就是您想要的。

此博客文章应包含您关注的详细信息:https://blog.angularindepth.com/rxjs-understanding-expand-a5f8b41a3602

关键部分是:

import { empty } from "rxjs/observable/empty";
import { concatMap, expand } from "rxjs/operators";
import { get } from "./get";

const url = "https://api.github.com/users/sindresorhus/repos";
const repos = get(url).pipe(
  expand(({ next }) => next ? get(next) : empty()),
  concatMap(({ content }) => content)
);
repos.subscribe(repo => console.log(repo));

其中get(url)返回带有ajax结果(content)和“下一个” URL的观察值(以获取下一个结果-在示例中保存在__next中)