从RxJS filter()谓词返回可观测值

从RxJS filter()谓词返回可观测值,filter,rxjs,reactive-programming,rxjs5,Filter,Rxjs,Reactive Programming,Rxjs5,RxJS中是否有一个运算符可以像filter()一样工作,但接受一个允许返回可观察值的谓词?因此,当谓词返回的Observable发出一个事件时,filter()决定是否应该丢弃来自原始源的事件。如果我理解正确,我会像下面这样做: const Observable = Rx.Observable; const Subject = Rx.Subject; let subject = new Subject(); source = Observable.from([1,2,3,4]) .fl

RxJS中是否有一个运算符可以像
filter()
一样工作,但接受一个允许返回可观察值的谓词?因此,当谓词返回的Observable发出一个事件时,
filter()
决定是否应该丢弃来自原始源的事件。

如果我理解正确,我会像下面这样做:

const Observable = Rx.Observable;
const Subject = Rx.Subject;

let subject = new Subject();

source = Observable.from([1,2,3,4])
  .flatMap(val => subject
    .withLatestFrom(Observable.of(val), (_, val) => val)
    .filter(val => val % 2 == 0)
  );

source.subscribe(val => console.log(val));

subject.next(null);
setTimeout(() => {
  subject.next(null);
}, 1000);
我用另一个Observable and操作符包装每个值,该操作符仅在其源发射时发射。在我的例子中,源代码是
subject
,所以我可以完全控制它。然后是
filter()
,它可以过滤任何你想要的东西

虽然,我想知道是否有更简单的解决办法

这只打印两个值,1s后再打印两个,因为我调用了
subject.next(null)
setTimeout
回调中:

2
4
2
4

请参阅现场演示:

另一种方法是使用两个
开关映射
操作符:

const animals$ = from(['cat', 'dog', 'fish']).pipe(switchMap(animal => {

    // call webservice to determine if the animal is a mammal or not
    // this returns an observable boolean (i.e. a predicate)
    // this could be any Observable<boolean> of course
    const isMammal$: Observable<boolean> = webService.isMammal(animal);

    // when we get the result back if it's true then return the 
    // original 'animal' string (by creating a new observable with of()) 
    // if it isn't an animal then return EMPTY, which has the same effect as filtering it out
    return isMammal$.pipe(switchMap(isMammal => isMammal ? of(animal) : EMPTY));
}))
const animals$=from(['cat','dog','fish')。管道(开关映射(animal=>{
//致电webservice以确定该动物是否为哺乳动物
//这将返回一个可观察的布尔值(即谓词)
//当然,这是可以观察到的
const isMammal$:Observable=webService.isMammal(动物);
//当我们返回结果时,如果结果为真,则返回
//原始的“动物”字符串(通过使用of()创建新的可观察字符串)
//如果它不是动物,则返回空的,这与过滤掉它的效果相同
返回isMammal$.pipe(switchMap(isMammal=>isMammal?of(animal):空);
}))

谢谢!我可以确认演示的行为符合我的预期,尽管对于这个场景来说,代码看起来确实有点太复杂了。我将尝试在接下来的几个小时内将其应用到我所想到的实际用例中,然后我会回来告诉您结果。