如何通过为我需要在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', fruit: 'apple', 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)),
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调用,但是我处理了项目的元数据:
const source = {animal: 'cat', fruit: 'apple', color: 'blue'}
const observables = Object.keys(source).map(key => of(key))
const processedObservable = forkJoin(observables).pipe(
map(items => items.map(item => '(' + item + ')')),
map(items => items.join(', '))
)
processedObservable.subscribe(text => console.log(text)) // test
// result: (animal), (fruit), (color)
我想得到这个结果:
// result: this is your cat (animal), this is your apple (fruit), 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
?
用于模拟API调用的方法getDataFromApi
:
getDataFromApi(item) {
return of('your ' + item)
}
答案 0 :(得分:1)
以下是如何实现的示例:
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
)),
toArray(), // <= 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>
答案 1 :(得分:1)
您应将第一个map
直接添加到创建各个可观察物的位置。
const source = { animal: "cat", fruit: "apple", 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);
答案 2 :(得分:0)
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})`),
toArray(),
map(data => data.join(', ')),
).subscribe(console.log);
答案 3 :(得分:0)
尝试使用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)
})