我对https://github.com/HackerNews/API有疑问。
我需要在第一页的30条新闻(标题,作者...)中获取Angular 7中的所有最佳新闻。如何使用下一个api发送获取请求?
此API显示了所有最佳故事的ID: https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty
此api显示一个故事的示例: https://hacker-news.firebaseio.com/v0/item/8863.json?print=pretty
我尝试:
loadItem(){
this.http.get(`https://hacker-
news.firebaseio.com/v0/item/${this.id}.json?print=pretty`).subscribe(data => {
this.items.push(data as any[]);
})
}
loadBestItems(){
this.http.get('https://hacker-news.firebaseio.com/v0/beststories.json?
print=pretty').subscribe(data => {
this.bestItems.push(data as any[]);
})
}
我需要第一页上的30条最佳新闻
答案 0 :(得分:1)
这是一个非常棘手的问题,但我认为我们可以将其分解为三个主要问题:
1。您如何限制黑客新闻api返回的故事数量?
由于黑客新闻数据是通过firebase API公开的,因此请参考firebase文档。如here所示,我们可以一起使用limitToFirst和orderBy选项来限制结果数。我们可以简单地通过键进行排序,因此您的请求URL最终看起来像这样:
'https://hacker-news.firebaseio.com/v0/beststories.json?
print=pretty&orderBy="$key"&limitToFirst=30'
2。您如何在Angular中链接HTTP请求(根据第二个请求的结果发出第二个请求)?
这可以通过mergeMap
rxjs operator来实现。该运算符允许您将一个可观察对象发出的值映射到另一个可观察对象。为简化起见,假设您最初的请求是仅返回一个ID。然后,我们可以使用mergeMap
将ID映射到完整项目的请求。
如果该端点存在于路径beststory.json
处,它将看起来像这样。
this.http.get('https://hack...v0/beststory.json').pipe(
mergeMap((id) => this.http.get(`https://hack.../v0/item/${id}`))
).subscribe((data) => {
console.log('Story: ', data);
}
但是,由于您需要映射到多个请求,因此我们将需要引入问题3中概述的另一个运算符。
3。如何同时发出多个HTTP请求(对列表中的每个项目发出请求)?
这可以通过forkJoin
rxjs运算符来实现。此运算符采用一个可观察值数组,并在它们全部完成后发出它们的值数组。在您遇到问题的情况下,输入是一个请求数组(初始请求中的每个ID一个),输出将是项目列表。为了简化起见,假设您已经有一组ID。发出对列表中每个项目的请求看起来像这样:
let ids = [1, 2,...];
forkJoin(ids.map((id) => this.http.get(`https://hack.../v0/item/${id}`)).subscribe((stories) => {
console.log('Stories:', stories);
});
将它们放在一起
现在,我们知道如何将请求的结果映射到mergeMap
到另一个可观察对象,并且我们知道如何将多个可观察到的结果与forkJoin
合并为一个,我们可以将它们一起使用达到您的期望:
this.http.get('https://hack....v0/beststories.json?orderBy="$key"&limitToFirst=30').pipe(
mergeMap((ids) => forkJoin(ids.map((id) => this.http.get(`https://hack...v0/item/${id}`)))),
).subscribe((stories) => {
console.log('Stories:', stories);
});
请注意,在代码段中,我排除了部分url和无关的查询参数