如何解决RxJS Observables数组以及要保留的其他数据
简短说明
如何通过为我需要在forkJoin
&pipe
中使用的每个Observable传递一些数据来处理可观察变量数组(例如,在map
中)?
const source = {animal: 'cat',fruit: 'apple',color: 'blue'}
const observables = Object.keys(source).map(key => [this.getDataFromApi(source[key]),key])
// resolve only observables[0][0],observables[0][1],observables[0][2] in magic way,// but preserve observables[1][0],observables[1][1],observables[1][2] for future use in pipe&map
const processedobservable = forkJoin(observables).pipe( // ???
map(items => items.map(item => 'this is ' + item[0] + '(' + item[1] + ')')),// this doesn't work
map(items => items.join(','))
)
processedobservable.subscribe(text => console.log(text)) // subscribe only for test
// expected result: this is your cat (animal),this is your apple (fruit),this is your blue (color)
详细说明
我有一些“源”(项目的数组或对象)。我需要向API请求每个项,因此我得到了Observables数组。
接下来,我要处理所有接收到的数据,因此我使用forkJoin
并在pipe
和几个map
中处理数据。
我无法直接处理订阅中的数据。
这是简单的示例:
const source = ['cat','apple','blue']
const observables = source.map(item => this.getDataFromApi(item))
const processedobservable = forkJoin(observables).pipe(
map(items => items.map(item => 'this is ' + item)),map(items => items.join(','))
)
processedobservable.subscribe(text => console.log(text)) // test
// result: this is your cat,this is your apple,this is your blue
但是除了API请求的项目数据外,我还拥有在pipe
和map
中处理期间必须使用的项目元数据。
这里是具有代表性来源的示例,但是这里我不使用项目的元数据(结果与上面相同)。我忽略了元数据:
const source = {animal: 'cat',color: 'blue'}
const observables = Object.keys(source).map(key => this.getDataFromApi(source[key]))
const processedobservable = forkJoin(observables).pipe(
map(items => items.map(item => 'this is ' + item)),this is your blue
这里是具有代表性来源的示例,但是在这里我忽略了键和API调用,但是我处理了项目的元数据:
const source = {animal: 'cat',color: 'blue'}
const observables = Object.keys(source).map(key => of(key))
const processedobservable = forkJoin(observables).pipe(
map(items => items.map(item => '(' + item + ')')),'))
)
processedobservable.subscribe(text => console.log(text)) // test
// result: (animal),(fruit),(color)
我想得到这个结果:
// result: this is your cat (animal),this is your blue (color)
通过某种方式在pipe
&map
中:
map(items => items.map(item => 'this is ' + item.apiValue + '(' + item.key + ')')),
或:
map(items => items.map(item => 'this is ' + item[0] + '(' + item[1] + ')')),
但是我不知道如何将可观察变量和元数据数组传递给forkJoin
,其中一些具有元数据的可观察变量数组:
const observables = Object.keys(source).map(key => [this.getDataFromApi(source[key]),key])
也许我应该使用其他功能,例如flatMap
或switchMap
?
其他信息
getDataFromApi(item) {
return of('your ' + item)
}
解决方法
以下是如何实现的示例:
from(Object.entries(source))
.pipe(
mergeMap(([key,value]) => getFromApi(value).pipe(
map(item => `this is ${item} (${key})`),// <= key is being closured
)),toArray(),// <= transform stream to array
map(item => item.join()),)
.subscribe(console.log);
尝试运行以下演示:
const { from,of } = rxjs;
const { map,switchMap,toArray } = rxjs.operators;
function getFromApi(item) {
return of('your ' + item)
}
const source = { animal: "cat",fruit: "apple",color: "blue" };
from(Object.entries(source))
.pipe(
mergeMap(([key,value]) => getFromApi(value).pipe(
map(item => `this is ${item} (${key})`),// <= key is being closured
)),// <= transform stream to array
map(item => item.join()),)
.subscribe(console.log);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.6.2/rxjs.umd.min.js"></script>
,
您应将第一个map
直接添加到创建各个可观察物的位置。
const source = { animal: "cat",color: "blue" };
const observables = Object.keys(source).map(key => getFromApi(source[key]).pipe(
map(item => `this is ${item} (${key})`)
));
const processedObservable = forkJoin(observables).pipe(
map(items => items.join(','))
);
processedObservable.subscribe(console.log);
https://stackblitz.com/edit/rxjs-4x7hbv?file=index.ts
,function getDataFromApi(item) {
return of('your ' + item)
}
const source = { animal: 'cat',fruit: 'apple',color: 'blue' };
from(Object.keys(source)).pipe(
switchMap(key => forkJoin([getDataFromApi(source[key]),of(key)])),map(([data,key]) => `this is ${data} (${key})`),map(data => data.join(',')),).subscribe(console.log);
请参阅:https://stackblitz.com/edit/rxjs-1t4nlo?file=index.ts
,尝试使用import { combineLatest } from 'rxjs'
combineLatest(['cat','apple','blue'].map(item => this.getDataFromApi(item))).pipe(
map(items => items.map(item => 'this is ' + item)),map(items => items.join(','))
)
.subscribe({
next:(res) => console.log(res)
})
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。