我在角度4应用程序中获得了一项服务,该应用程序从后端API检索可变数量的页面。
我在这里查看答案Angular 2 - Chaining http requests,建议使用flatMap,但这种方法不起作用,因为它要求事先知道所有请求。这在我的情况下不起作用,因为请求的数量和每个请求的URL是动态的并且是未知的。
从上一个请求的结果推断出页数/请求数。因此,如果先前的请求返回任何内容,则请求下一页以查看是否还有其他项目。
我尝试了以下
this.items = [];
_fetch(url, page) {
this.http.get(`${url}&pageSize=2&page=${page}`).subscribe(response => {
this.items.concat(response.json().items)
// if the list of items is not empty fetch another page
if (response.json().items.length > 0) {
this._fetch(url, ++page);
}
});
return Observable.of(this.items);
}
但是,在请求有机会完成之前会返回this.items
,因此它总是作为空列表返回。
任何想法?
答案 0 :(得分:2)
您可以使用flatMap将可观察量链接在一起
fetch(url){
return this.http.get(`${url}/initial-api/`)
.flatMap(res => {
let page = res.page
return this.get(`${url}&pageSize=2&page=${page}`);
});
}
现在,当您订阅可观察序列时,它会将api链接在一起
这是对flatMap / mergeMap的一个很好的阅读:https://coryrylan.com/blog/angular-multiple-http-requests-with-rxjs
flatMap的优点在于它将事物保存在单个流中,而不是嵌套订阅,根据您的代码,嵌套订阅会变得非常混乱。
答案 1 :(得分:0)
由于.subscribe
返回一个observable,你可以简单地链接它们。只要没有错误,它就会执行第二个错误:
this.http.get('some url').subscribe( result => {
if (result) {
// good to go execute second call.
this.http.get('other url').subscribe( result2 => {
// do something with result 1 and result 2
})
} else {
// handle error. don't execute second call
}
}, error => {
// error occured. don't execute second call
})
您也可以在应用中设置承诺,如下所示:
firstHttpCall() {
return new Promise( (resolve, reject) => {
this.http.get('someurl').subscribe( result => {
result(result);
}, error => {
reject(error);
});
});
}
secondHttpCall() {
return new Promise( (resolve, reject) => {
this.firstHttpCall().then( result => {
resolve(result);
}, error => {
reject(error);
});
});
}
someOtherCall() {
// some stuff...
this.secondHttpCall().then( result => {
// everything went well.
}, error => {
// something went wrong
})
}
如果你可以达到你不依赖第二次通话中使用的第一个通话值的程度,我会说Promise.all
也是可行的选择。