我尝试查询所有人员的数据swap api http://swapi.co/。 URL swapi.co/api/people 返回一个带有 people 数组的对象,以及我从中获取下一个数据的 URL(swapi.co/api/people/?page=2)。我想要做的是,每次有新页面可用时,订阅方法都会更新角度分量。
我是反应式编程模型的新手。如何实现 while 循环或 Observables 序列?
这适用于第一页:
getAllPeople(): Observable<Person[]> {
let nextUrl = http://swapi.co/api;
let source = Observable.create(observer => {
this.http.get(nextUrl, { headers: this.headers })
.map(response => {
let body = response.json();
nextUrl = body.next;
return nextUrl != null ? body.results as Person[] : null;
}
)
.retry(5)//send same request based on the url of the previous request till the field next is null
.catch(error => observer.error(error))
.subscribe(persons => {
if (persons !== null) {
observer.next(persons)
}
}
);
//observer.complete();
})
return source;
}
编辑:
我添加了 retry() 方法。我希望更容易理解我打算做什么。在第一个请求之后,它会向同一 URL 发送更多请求。不幸的是,它没有使用我从上一个请求中获得的新 URL。
http://swapi.co/api/?page=1 http://swapi.co/api/?page=1 -> http://swapi.co/api/?page=2 http://swapi.co/api/?page=2 -> http://swapi.co/api/?page=3 http://swapi.co/api/?page=3-> 空
我不知道需要多少个请求才能检索所有数据。
通过使用expand
您可以为每个返回的值创建一个新的 Observable 序列。停止expand
从创建任何新序列开始,一旦我们得到一个为 null 的下一个 URL,我们就可以返回一个空的 Observable 以停止扩展我们的序列。最后,我们可以使用一个reduce
运算符将不同的数据页聚合到一个数组中,然后将其发送回原始订阅者。这可以通过以下方式完成:
public getAllPeople(): Observable<Person[]> {
return Observable.create(observer => {
this.getPage("http://swapi.co/api/people/")
.expand((data, i) => {
return data.next ? this.getPage(data.next) : Observable.empty();
})
.reduce((acc, data) => {
return acc.concat(data.results);
}, [])
.catch(error => observer.error(error))
.subscribe((people) => {
observer.next(people);
observer.complete();
});
});
}
private getPage(url: string): Observable<{next: string, results: Person[]}> {
return this.http.get(url, { headers: this.headers })
.map(response => {
let body = response.json();
return {
next: body.next,
results: body.results as Person[]
};
}
);
}
Demo http://plnkr.co/edit/c0F5eSoswCfi0dt2pA3r?p=preview
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)