这看起来像concatMap
operator工作(顺便说一句,我有一个非常类似的问题前段时间How to use exhaustMap in ReactiveX/rxjs 5 in TypeScript)。
比如为了运行几个请求:
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/concatMap';
import 'rxjs/add/operator/do';
var urls = [
'https://httpbin.org/get?1',
'https://httpbin.org/get?2',
'https://httpbin.org/get?3',
'https://httpbin.org/get?4',
'https://httpbin.org/get?5',
];
Observable.from(this.urls)
.concatMap(url => http.get(url))
.subscribe(response => console.log(response.url))
;
此打印到控制台:
https://httpbin.org/get?1
https://httpbin.org/get?2
https://httpbin.org/get?3
https://httpbin.org/get?4
https://httpbin.org/get?5
算concatMap()
每个值(在我们的情况下,每个URL)映射到一个Observable
和再发射所有的值直到完成。然后继续从可调用函数返回的下一个Observable
。我们知道http.get()
返回的Observable
仅与Response
对象发出一个值,然后完成。
见plnkr演示:http://plnkr.co/edit/PJ7SpkNgBjZz2h4uvRpK?p=preview(在app.component.ts
)
你说的要求是互相依赖的(一个请求是依赖于前一个请求的结果?),所以也许更好的解决方案可能是以下几点:
http.get('https://httpbin.org/get?1')
.do(response => console.log('Process response', response.url))
.concatMap(response => {
console.log('Previous response', response.url, ' about to run /get?2')
return http.get('https://httpbin.org/get?2')
})
.do(response => console.log('Process response', response.url))
.concatMap(response => {
console.log('Previous response', response.url, ' about to run /get?3')
return http.get('https://httpbin.org/get?3')
})
.subscribe(response => console.log('Done', response.url))
;
输出控制台:
Process response https://httpbin.org/get?1
Previous response https://httpbin.org/get?1 about to run /get?2
Process response https://httpbin.org/get?2
Previous response https://httpbin.org/get?2 about to run /get?3
Done https://httpbin.org/get?3
同样,我们使用concatMap()
把每个值到Observable
,但是这次我们使用它来保证正确的顺序并能够访问前面的http.get()
调用的结果。我还使用do()
operator来分离逻辑,该逻辑处理来自逻辑的先前响应,该逻辑创建下一个更好可读性的请求(尽管这可能全部进入concatMap()
)。 (在app.component.ts
)