如何简单地循环一个observable?
假设我想要执行一次可观察的五次,它会像下面的代码一样。
我的代码中发生了什么
(1)我查询并且函数返回一个名为'posts'的json
(2)对于我想要执行可观察的每个“帖子”
(3)我将步骤(2)的结果推送到我的数组
// (1)
this.communityPostProvider.query({})
.subscribe(posts => {
// (2)
for(let i=0; i < posts.length; i++) {
this.getFeaturedApi(i)
.subscribe(result => {
// (3)
this.communityPosts.push(posts[i]);
this.communityPosts[i].featured_media = result;
});
});
这个问题是for循环在我的observable之前完全执行。到observable执行时,for循环已经完成。
我是angular2的新手。请帮忙!
答案 0 :(得分:0)
试试这个:
this.communityPostProvider.query({})
.map(posts => {
for(var i=0; i<posts.length; i++){
this.getFeaturedApi(i)
.subscribe(result=> {
posts[i].featured_media = result;
this.communityPosts.push(posts[i]);
}
return posts;
})
.subscribe(posts => {
// your posts with featured_media
});
如果使用rxjs&gt; = 5.5,请使用.pipe(map(...))
要了解如何使用地图和其他rxjs运算符here
要了解新的rxjs可调函数,here
答案 1 :(得分:0)
如果您能够在功能中编辑代码
this.getFeaturedApi(i)
当你返回结果时,只需通过&#34; i&#34;返回结果,所以端点将知道推入数组的索引。
例如。
this.getFeaturedApi(i:number){
// your code
return {result:result, index:i};
并在你的for循环中
// (2)
for(let i=0; i < posts.length; i++) {
this.getFeaturedApi(i)
.subscribe(result => {
// (3)
this.communityPosts.push(posts[result.index);
this.communityPosts[result.index].featured_media = result.result;
});
现在你用索引收到结果了。所以你确切地知道推入数组的索引。
希望它会有所帮助。
答案 2 :(得分:0)
您应该能够将flatMap
与range
和combineLatest
结合使用,以获得更好的结果。
此版本与您的结构非常相似。
this.communityPostProvider.query({})
.flatMap(posts => {
return Observable.range(0, posts.length-1)
.map(i=> {
return {index: i, post: posts[i]};
})
})
.flatMap(postWithIndex => Observable.forkJoin([Observable.of(postWithIndex), this.getFeaturedApi(postWithIndex.index)])
.subscribe(result => {
// result = [{index: i, post: posts[i]}, resultFromFeature]
this.communityPosts.push(result[0].post]);
this.communityPosts[result[0].index].featured_media = result[1];
});
但我建议重构一下,因为它更清洁,更符合流媒体API。
this.communityPostProvider.query({})
.flatMap(posts => {
return Observable.range(0, posts.length-1)
.map(i=> {
return {index: i, post: posts[i]};
})
})
.flatMap(postWithIndex => Observable.forkJoin([Observable.of(postWithIndex.post), this.getFeaturedApi(postWithIndex.index)]))
.map(postAndResult => {
// result = [post, resultFromFeature]
postAndResult[0].featured_media = postAndResult[1]
return postAndResult[0];
})
.subscribe(postWithFeaturedMedia => {
this.communityPosts.push(postWithFeaturedMedia);
});
(这是未经测试的,因为我没有工作rxjs设置atm。)
答案 3 :(得分:0)
这也是未经测试的。
mergeMap将获取一个值并返回内部可观察数据。
因此我们采用帖子数组并使用Observable的from运算符分别发出数组的每个项目,再次使用mergeMap将每个值映射到一个observable,在这种情况下,observable从调用getFeaturedApi
,传入给我们的索引作为mergeMap的参数。
我们使用map将检索到的feature
分配给关联的post
。
this.communityPostProvider.query({})
.mergeMap((posts) => {
return Observable.from(posts).mergeMap((post, index) => {
this.communityPosts.push(post);
return this.getFeaturedApi(index).map((feature) => {
this.communityPosts[index] = feature;
return feature;
});
});
})
.subscribe();
根据您的需要,您可以从feature
上运行的地图返回post
或getFeaturedApi
。返回的内容将在subscribe
函数中提供。