我有一个应用程序,它发出一个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());
}
}
然后我会做像_1383009这样的事情,但最终发生的事情是我得到一个可观察数组(每个响应来自 fetchItem
) . 我还需要订阅每个内部observable,以便实际触发 fetchItem
请求 .
我也尝试使用 flatMap
而不是map,但在这种情况下似乎有相同的结果 . 是否有任何方法可以订阅嵌套的observable?
3 回答
我会像下面这样做:
观看现场演示:http://plnkr.co/edit/LPXfqxVsI6Ja2J7RpDYl?p=preview
我正在使用.concatAll()的技巧将一个对象数组(如
[{"id": 1}, {"id": 2}, {"id": 3}]
)转换为逐个发出的单独值{"id": 1}
,{"id": 2}
和{"id": 3}
(截至目前它是一个未记录的功能) . 然后我使用mergeMap()在单独的请求中获取其内容并将其结果合并到运算符链中 .这个plnkr示例打印到控制台:
您可能遇到的问题是您没有足够扁平 .
flatMap
或mergeMap
将展平Observables
,Promises
,Arrays
,甚至generators
(不要在最后一个引用我),几乎任何你想扔的东西 .所以当你做
.flatMap(items => items.map(item => this.fetchItem(item))
时,你真的只是在做Observable<Array<Item>> => Observable<Observable<Item>>
当你做
map
时,你正在做Observable<Array<Item>> => Observable<Array<Observable<Item>>>
.您需要做的是首先展开数组,然后展平每个请求:
现在,如果您不介意单独获取每个项目响应,则上述工作正常 . 如果你需要获得所有项目,那么你应该在所有内部值上使用forkJoin,但是为了展平得到的内部值,你仍然需要
flatMap
:您可以在调用
this.fetchItem
的行之前拆分items数组 . 您可以在Observable上使用mergeMap,其值是一个数组,每个项目将单独发出 .编辑:我想我应该提供更多解释 .
mergeMap
与rxjs中的flatMap
同义 . 通常,当你的投影函数返回一个Observable时你使用flatMap,但它也会使数组变平,所以,调用mergeMap然后将单独发出每个项目,我认为这是OP想要实现的 . 我也意识到,你可以组合mergeMap
调用和最后map
调用,因为将为数组中的每个项调用mergeMap
的投影,我在上面的代码中进行了更改 .