Typescript 获取和合并可观察的响应数组
对于可观察数组中的每个值,获取一个数字数组,将所有结果合并到一个可观察的数字数组中 我尝试了Typescript 获取和合并可观察的响应数组,typescript,rxjs,Typescript,Rxjs,对于可观察数组中的每个值,获取一个数字数组,将所有结果合并到一个可观察的数字数组中 我尝试了flatMap和concatMap的各种组合,但都做不好 someFunction(): Observable<number[]> { // Observable<string[]> const strings = of(['a', 'b', 'c']); let index = 0; // Observable<number[]> const
flatMap
和concatMap
的各种组合,但都做不好
someFunction(): Observable<number[]> {
// Observable<string[]>
const strings = of(['a', 'b', 'c']);
let index = 0;
// Observable<number[]>
const numbers = strings.pipe(
flatMap(ids => ids.map(() => of([index++, index++, index++])))
);
return numbers; // [1, 2, 3, 4, 5, 6, 7, 8, 9]
}
someFunction():可观察{
//可观察
常量字符串=of(['a','b','c']);
设指数=0;
//可观察
常量编号=strings.pipe(
flatMap(ids=>ids.map(()=>of([index++,index++,index++]))
);
返回数字;//[1,2,3,4,5,6,7,8,9]
}
查看您的代码,Bar
Observable发出一个类型为Bar[]
的实例,作为ObservablefooIds
发出一个id数组的结果
如果是这种情况,这里可能需要注意两件事
第一个是使用switchMap
。使用此操作符,您可以在源可观测中的另一个发射发生时立即完成任何正在运行的可观测
换句话说,如果fooIds
以非常快的顺序或同步地发出两个ID数组,那么当第二个ID到达时,bar
尚未完成对第一个ID数组的处理,那么第一个ID将被忽略,只处理第二个ID。如果您想保留所有的结果,您可能需要考虑使用<代码> CyMeMAP(A.K.A.代码>平版图< /代码>),而不是<代码>
第二件事是使用concatAll
。使用此操作符,您希望保留源可观测的序列。生成的可观察对象将始终发出类型为bar[]
的单个实例,其中包含使用fooIds
的单个通知传递的ID检索到的所有bar
如果您要实现的结果是一个包含“所有代码来自<代码> > FooID的所有条目的<代码> bar B/C> >,您可以考虑使用<代码> Reals运算符,如以下方式
reduce((acc, one: any) => {
acc = acc.concat(one);
return acc;
}, []),
在@hdk发表评论后更新了答案
这应该是使您的示例工作的代码
function someFunction(): Observable<number[]> {
// Observable<string[]>
const strings = of(['a', 'b', 'c']);
let index = 0;
// Observable<number[]>
const numbers = strings.pipe(
mergeMap(ids => ids.map(() => of([index++, index++, index++]))),
mergeMap(d => d) // flattens the Observable<Observable<number>> to Observable<number>
);
const numbersReduced = numbers
.pipe(
reduce((acc: Array<number>, one: Array<number>) => {
acc = acc.concat(one);
return acc;
}, new Array<number>()),
);
return numbersReduced// [1, 2, 3, 4, 5, 6, 7, 8, 9]
}
someFunction().subscribe(console.log)
返回可观察的
为什么??因为ids.map(..)
返回一个数组
,它是一个可观察的输入
mergeMap
需要一个返回ObservableInput
的函数作为输入,因此一个返回数组的函数就足够了。如果该数组
(如本例所示)本身包含其他可观察对象,那么您就可以得到我们所看到的可观察对象
返回类型
剩下的应该或多或少简单明了
在现实世界中,例如,如果您处理http请求,您可以使用其他策略,例如使用forkJoin
。在这种情况下,代码就是这样的
function someFunction(): Observable<number[]> {
// Observable<string[]>
const strings = of(['a', 'b', 'c']);
let index = 0;
const numbers = strings.pipe(
mergeMap(ids => {
const numberObservables = ids.map(() => of([index++, index++, index++]));
return forkJoin(numberObservables)
})
);
const numbersReduced = numbers
.pipe(
map(arrayOfArrayOfNumbers => arrayOfArrayOfNumbers
.reduce(
(acc: Array<number>, one: Array<number>) => {
acc = acc.concat(one);
return acc;
}, new Array<number>()
))
)
return numbersReduced// [1, 2, 3, 4, 5, 6, 7, 8, 9]
}
function someFunction():可观察{
//可观察
常量字符串=of(['a','b','c']);
设指数=0;
常量编号=strings.pipe(
合并映射(ID=>{
const numberObservables=ids.map(()=>of([index++,index++,index++]);
返回forkJoin(numberObservables)
})
);
常数numbersReduced=个数
.烟斗(
映射(arrayOfArrayOfNumbers=>arrayOfArrayOfNumbers
.减少(
(acc:Array,one:Array)=>{
acc=acc.concat(一个);
返回acc;
},新数组()
))
)
返回数字减少//[1,2,3,4,5,6,7,8,9]
}
请注意,您仍在使用reduce
,但这次使用的是Array
reduce
方法,而不是我们在上一个案例中使用的observative
reduce
方法。感谢您的帮助。Reduce应该是正确的方法,但我仍然不能正确地得到它。我已经根据您的评论和您问题的编辑版本更新了我的答案
function someFunction(): Observable<number[]> {
// Observable<string[]>
const strings = of(['a', 'b', 'c']);
let index = 0;
const numbers = strings.pipe(
mergeMap(ids => {
const numberObservables = ids.map(() => of([index++, index++, index++]));
return forkJoin(numberObservables)
})
);
const numbersReduced = numbers
.pipe(
map(arrayOfArrayOfNumbers => arrayOfArrayOfNumbers
.reduce(
(acc: Array<number>, one: Array<number>) => {
acc = acc.concat(one);
return acc;
}, new Array<number>()
))
)
return numbersReduced// [1, 2, 3, 4, 5, 6, 7, 8, 9]
}