我有一个应用程序,它发出一个http请求来获取项目列表,然后为列表中的每个项目发出一个http请求,以获取有关每个项目的更多详细信息.有效:
class ItemsService { fetchItems() { return this.http.get(url) .map(res => res.json()) .map(items => items.map(this.fetchItem(item))); } fetchItem(item: Item) { this.http.get(`${url}/${item.id}`) .map(res => res.json()); } }
然后我将执行itemsService.fetchItems().subscribe(items => console.log(items))之类的操作,但最终发生的事情是我得到一个observable数组(来自fetchItem的每个响应).我还需要订阅每个内部observable,以便实际触发fetchItem请求.
我也试过使用flatMap而不是map,但在这种情况下似乎有相同的结果.是否有任何方法可以订阅嵌套的observable?
解决方法
我会像下面这样做:
function mockRequest() { return Observable.of('[{"id": 1},{"id": 2},{"id": 3}]'); } function otherMockRequest(id) { return Observable.of(`{"id":${id},"desc": "description ${id}"}`); } class ItemsService { fetchItems() { return mockRequest() .map(res => JSON.parse(res)) .concatAll() .mergeMap(item => this.fetchItem(item)); } fetchItem(item: Item) { return otherMockRequest(item.id) .map(res => JSON.parse(res)); } } let service = new ItemsService(); service.fetchItems().subscribe(val => console.log(val));
观看现场演示:http://plnkr.co/edit/LPXfqxVsI6Ja2J7RpDYl?p=preview
我正在使用.concatAll()
的技巧将[{“id”:1},{“id”:2},{“id”:3}]等对象数组转换为逐个发出的单独值{“ id“:1},{”id“:2}和{”id“:3}(截至目前它是一个未记录的功能).然后我使用mergeMap()
在单独的请求中获取其内容,并将其结果合并到运算符链中.
这个plnkr示例打印到控制台:
{ id: 1,desc: 'description 1' } { id: 2,desc: 'description 2' } { id: 3,desc: 'description 3' }