我对RxJS比较陌生。我知道我可以使用.filter
和.map
操作符来获取我需要的结果。但是,是否有一种方法将这两个操作结合成一个函数呢?
我对RxJS比较陌生。我知道我可以使用.filter
和.map
操作符来获取我需要的结果。但是,是否有一种方法将这两个操作结合成一个函数呢?
有的。
FlatMap。
假设你有一个数字的 Observable (1、2、3、4、5,...),并且你想筛选出偶数并将它们映射为 x*10。
var tenTimesEvenNumbers = numbers.flatMap(function (x) {
if (x % 2 === 0) {
return Rx.Observable.just(x * 10);
} else {
return Rx.Observable.empty();
}
});
if
语句的括号内完成。假设您有一个常见的过滤函数,想要将其应用于多次操作,您仍然可以这样做,但需要编写多个if()语句。此外,每次都需要调用它。更好的解决方案是,您可以将过滤和映射函数作为单独的参数传递。在我看来,一种能够实现这种编码风格的解决方案更具“功能性”。 - Bryan Rayner.flatMap(x => x % 2 == 0 ? [x * 10] : [])
。 - phauxflatMap
现在被称为 mergeMap
: https://github.com/ReactiveX/RxJS/issues/333 - Mihai Răducanu // Initialise observable with some numbers
const numbers = of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// Pipe the observable using mergeMap
const tenTimesEvenNumbers = numbers.pipe(
mergeMap((x: number) => {
// If the number is even, return an observable containing the number multiplied by ten
// Otherwise return an empty observable
return x % 2 === 0 ? of(x * 10) : EMPTY;
})
);
// Subscribe to the observable and print the values
tenTimesEvenNumbers.subscribe((value: number) =>
console.log('Value:', value)
);
Value: 20
Value: 40
Value: 60
Value: 80
Value: 100
这里也有一个可工作的stackblitz 示例。
function filterMap<A, B>(filterFn: (a: A) => boolean, mapFn: (a: A) => B): (as: A[]) => B[] {
return (as) => as.reduce((acc, a) => {
if (filterFn(a)) acc.push(mapFn(a));
return acc;
}, []);
}
const isEven = (a) => a % 2 === 0;
const doubleValue = (a) => a = 2 * a;
const doubleEvens = filterMap(isEven, doubleValue);
const myResult = doubleEvens([1, 2, 3, 4, 5);
of([1, 2, 3, 4, 5]).pipe(
map(doubleEvens)
).subscribe(console.log);
有几个优点
filterApplyMap
类似于filterMap
,但添加else子句并执行acc.push(a)
,最终返回类型将是(A|B)[],与#1相同,这不太美观 3)定义filterPartitionMap
,它将一对列表作为累加器,并将适当的值推送到适当的列表上。返回类型将是[A[], B[]]。我将B[]放在右边以保持“true”值在右边的一致性。 - undefined