filter操作符在BehaviorSubject与from创建的Observable中表现差异问题
filter操作符在BehaviorSubject与from创建的Observable上的表现差异原因
你遇到的问题核心是两者发射的数据类型完全不同,并非filter操作符本身的行为差异:
1. 两种Observable的发射数据类型对比
方式1:BehaviorSubject定义的person$
person$的类型是BehaviorSubject<IPerson[]>,它每次发射的是整个人员数组,而非单个人员对象:
interface IPerson { name: string; age: number; } const person$ = new BehaviorSubject<IPerson[]>([ { name: "amir", age: 20 }, { name: "hosein", age: 10 }, ]);
方式2:from操作符定义的source$
from([...])会把数组转换成Observable,逐个发射数组中的每个IPerson对象,所以source$的类型是Observable<IPerson>:
const source$ = from([ { name: "amir", age: 20 }, { name: "hosein", age: 10 } ]);
2. 代码不工作的原因
对person$使用filter时,你写的逻辑是判断person.age <15,但这里的person实际是整个IPerson[]数组——数组没有age属性,所以person.age会返回undefined。undefined <15的结果是false,filter会把这个数据过滤掉,自然没有任何输出。
而source$发射的是单个IPerson对象,person.age能正确获取到数值,所以filter逻辑正常生效,筛选出年龄小于15的对象并输出。
3. 修正BehaviorSubject的筛选逻辑
如果你想实现和source$相同的效果(筛选出单个符合条件的人员对象),可以先把数组拆分成单个对象再筛选:
import { mergeMap } from 'rxjs/operators'; const filteredPerson$ = person$.pipe( mergeMap(people => from(people)), // 将数组拆分为单个对象发射 filter((person) => person.age < 15), tap((person) => console.log("person", person)), ); const observer1 = filteredPerson$.subscribe();
如果只是想过滤数组并保留数组形式,可以用map结合数组的filter方法:
const filteredPerson$ = person$.pipe( map(people => people.filter(person => person.age <15)), tap(filteredPeople => console.log("filtered people", filteredPeople)), );
内容的提问来源于stack exchange,提问作者amir tbi
相关产品推荐
相关产品推荐

