[英]RXJS convert single observable to array of observables
I have an API ( getNewStories ) that returns the data as an array of numbers(ids)
such as [1,2,3,4...].我有一个 API ( getNewStories ),它将数据作为numbers(ids)
数组返回,例如 [1,2,3,4...]。 There is another API ( getItem ) that uses the number(id)
and give its details.还有另一个 API ( getItem ) 使用number(id)
并提供其详细信息。
How can I accomplish this with rxjs operators, so that I should only subscribe to it once and it gives me an array of the records with those ids?如何使用 rxjs 运算符完成此操作,这样我应该只订阅一次它,它会给我一个带有这些 id 的记录数组?
I am able to accomplish this using 2 subscriptions, but I want it with one.我可以使用 2 个订阅来完成此操作,但我想要一个。 Is it possible?可能吗? and if it's, then, how?如果是,那么,如何?
this.hnService.getNewStories().subscribe(data => {
// data is [1,2,3,4,5]
// create an array of observables for all the ids and get the record for that id
const observables = data.map(item => this.hnService.getItem(item));
// use forkJoin to combine the array to single results variable
forkJoin(...observables).subscribe(results => {
this.stories = results;
});
});
with this I have to subscribe to both the APIs.有了这个,我必须订阅这两个 API。
You were going the right direction with using forkJoin
:您使用forkJoin
正确的方向前进:
this.hnService.getNewStories()
.pipe(
concatMap(data => {
const items$ = data.map(item => this.hnService.getItem(item));
return forkJoin(...items$);
}),
)
.subscribe(allItems => ...);
forkJoin
will wait until all source Observables complete and only then emit all results as a single array. forkJoin
将等待所有源 Observables 完成,然后才将所有结果作为单个数组发出。
I think you can achieve this using a flattening operator like this.我认为您可以使用这样的展平运算符来实现这一点。
this.hnService.getNewStories().pipe(
.mergeMap(data => this.hnService.getItem(data))
.subscribe(res => this.stories = res);
Other option can be to create two observable streams and use a combineLatest.其他选项可以是创建两个可观察的流并使用 combineLatest。
You can simply have implemented as in the the following snippet: (Yes, mergeAll
flattens an observable containing an array, for further explanation refer to @Martin's
post about the Best way to “flatten” an array inside an RxJS Observable )您可以简单地按照以下代码片段实现:(是的, mergeAll
将包含数组的可观察对象展平,有关进一步说明,请参阅@Martin 关于“展平” RxJS 可观察对象内的数组的最佳方法@Martin's
帖子)
getNewStories().pipe(mergeAll(), concatMap(this.getItem), toArray()).subscribe()
You can try running the following snippet:您可以尝试运行以下代码段:
const { of } = rxjs; const { concatMap, toArray, mergeAll } = rxjs.operators; function getItem(x) { return of({ item: x }) } of([1, 2, 3, 4]).pipe( mergeAll(), concatMap(getItem), toArray() ).subscribe(console.log)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.6.2/rxjs.umd.min.js"></script>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.