C. *_*rns 2 observable rxjs typescript angular2-http angular
寻找Observable http序列的帮助,我想对api进行两次http调用,第二次依赖于第一次.第一个返回一个Urls数组,第二个为该数组中的每个url生成get请求,然后返回流上的响应.如果我在其中一个依赖请求中硬编码,那么我会找回我正在寻找的一个标题:
search(character): Observable<any> {
let that = this
let queryUrl: string = character.url;
return this.http.get(queryUrl)
.map((response: Response) => {
this.characterResults = response.json().films
return this.characterResults
//Example response:
// ["https://api.com/films/1", "https://api.com/films/2", "https://api.com/films/3", "https://api.com/films/4"]
})
.flatMap((film) => {
return that.http.get(film[0])
.map((response: Response) => {
return response.json().title
})
})
}
getApiData(character) {
this.apiService.search(character)
.subscribe((results) => { // on sucesss
console.log(results)
},
(err: any) => { // on error
console.log(err);
},
() => { // on completion
console.log('complete')
}
);
Run Code Online (Sandbox Code Playgroud)
但任何尝试使用forEach迭代该数组然后进行所有http调用都会给我这个错误:
browser_adapter.js:84 EXCEPTION: TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined
Run Code Online (Sandbox Code Playgroud)
理想情况下,我想要一个优雅的方法,使第一次调用的结果数组与后续调用并行,但我似乎无法弄清楚哪些rxJ的数十种方法可以帮助我做到这一点.任何人都可以给我任何帮助吗?
有两种方法,如果你想让每个结果单独流式传输,那么flatMap就是你的朋友.你可以用它来拉平任何事情,Arrays,Promises,或Observables.在您的情况下,您可以通过执行以下操作来链接请求:
search(character): Observable<any> {
return this.http.get(character.url)
.flatMap((response: Response) => response.json().films)
.flatMap((film: string) => this.http.get(film),
(_, resp) => resp.json().title)
}
getApiData(character) {
this.apiService.search(character)
.subscribe((results) => { // on sucesss
//Called for each url result
console.log(results)
},
(err: any) => { // on error
console.log(err);
},
() => { // on completion
console.log('complete')
}
);
Run Code Online (Sandbox Code Playgroud)
或者您可以使用它forkJoin来返回结果数组
return this.http.get(character.url)
.flatMap((response: response) =>
//Waits until all the requests are completed before emitting
//an array of results
Observable.forkJoin(response.json().files.map(film =>
this.http.get(film).map(resp => resp.json().title)
));
Run Code Online (Sandbox Code Playgroud)
编辑1
flatMap更完整地解决第二个论点.它是一个函数,它接收传递给第一个选择器方法的原始值,并与展平操作的结果配对.也就是说,如果选择器1接收a和返回Observable的[1, 2, 3].第二个选择器将使用参数(a,1),(a,2)和(a,3)调用3次.
如果您想获得多个值,我建议您使用辅助映射运算符来保持流清洁,但这取决于您.
.flatMap((film: string) => this.http.get(film),
(film: string, resp: Response) => resp.json())
//Typescript's destructuring syntax, extracts the values you want
//and creates a new object with only those fields
.map(({date, title}) => ({date, title}));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4965 次 |
| 最近记录: |