通过承诺过滤数组
Filter array observable by promise
我有
- 对象数组
- 函数
permission(obj): Promise<boolean>
如何通过承诺过滤这个数组?
我尝试了很多东西,最接近的是
of(arr).pipe(
switchMap(items =>
from(items)
.pipe(
mergeMap(item =>
fromPromise(permission(item)).pipe(
map(shown => ({show, item})),
filter(data => data.shown),
map(data => data.item)
)
))
));
但这似乎是不必要的复杂。
我曾希望我能像 of(arr).pipe(filterByPromise(permission))
那样把它做得更简单,但似乎无法弄清楚该怎么做。
我做了一个 Stackblitz https://stackblitz.com/edit/rxjs-g1u8yk
StackBlitz 代码
import { of } from 'rxjs';
import { map, filter } from 'rxjs/operators';
// Mocked 3rd party function
function visible(obj): Promise<boolean> {
return new Promise(resolve => {
const shouldShow = obj.shouldShow < 30;
resolve(shouldShow);
});
}
const arr = [{
shouldShow: 39,
data1: 'abc',
data2: 'bcd'
}, {
shouldShow: 22,
data1: 'cde',
data2: 'def'
}];
of(arr).pipe(
filter(obj => visible(obj))
).subscribe(result => console.log(result));
JB Nizet nice solution, but it would be better to use concatMap
, if item order matters. Here 解释了 concatMap
和 mergeMap
之间的区别。
from(arr).pipe(
concatMap(element => from(visible(element)).pipe(
filter(show => show),
map(() => element)
))
).subscribe(console.log);
另一种方法是变换 zip 数组,就像这样。但是我认为解决方案更优雅。
zip(...arr.map(obj => from(visible(obj)))).pipe(
map(visible => arr.filter((item, i) => visible[i]))
).subscribe(console.log);
Here is 两种解决方案的工作示例。
我有
- 对象数组
- 函数
permission(obj): Promise<boolean>
如何通过承诺过滤这个数组?
我尝试了很多东西,最接近的是
of(arr).pipe(
switchMap(items =>
from(items)
.pipe(
mergeMap(item =>
fromPromise(permission(item)).pipe(
map(shown => ({show, item})),
filter(data => data.shown),
map(data => data.item)
)
))
));
但这似乎是不必要的复杂。
我曾希望我能像 of(arr).pipe(filterByPromise(permission))
那样把它做得更简单,但似乎无法弄清楚该怎么做。
我做了一个 Stackblitz https://stackblitz.com/edit/rxjs-g1u8yk
StackBlitz 代码
import { of } from 'rxjs';
import { map, filter } from 'rxjs/operators';
// Mocked 3rd party function
function visible(obj): Promise<boolean> {
return new Promise(resolve => {
const shouldShow = obj.shouldShow < 30;
resolve(shouldShow);
});
}
const arr = [{
shouldShow: 39,
data1: 'abc',
data2: 'bcd'
}, {
shouldShow: 22,
data1: 'cde',
data2: 'def'
}];
of(arr).pipe(
filter(obj => visible(obj))
).subscribe(result => console.log(result));
JB Nizet concatMap
, if item order matters. Here 解释了 concatMap
和 mergeMap
之间的区别。
from(arr).pipe(
concatMap(element => from(visible(element)).pipe(
filter(show => show),
map(() => element)
))
).subscribe(console.log);
另一种方法是变换 zip 数组,就像这样。但是我认为解决方案更优雅。
zip(...arr.map(obj => from(visible(obj)))).pipe(
map(visible => arr.filter((item, i) => visible[i]))
).subscribe(console.log);
Here is 两种解决方案的工作示例。