从Observable <T>中过滤所有'null'值

fas*_*sth 9 javascript observable rxjs typescript angular

我有一个主题的服务:

@Injectable() export class UserService() {
    private currentUserSubject = new BehaviorSubject<User>(null);
    public currentUser = this.currentUserSubject.asObservable().distinctUntilChanged(); 

    ... // emitting new User    
}
Run Code Online (Sandbox Code Playgroud)

有一个组件我将此服务注入并订阅更新:

@Component() export class UserComponent {
    constructor(private userService: UserService) {
        this.userService.currentUser
            .subscribe((user) => {
                // I want to see not null value here
            })
    }
}
Run Code Online (Sandbox Code Playgroud)

我想应用一些东西来Observable<User>过滤所有空值,只有在User实际加载时才进入订阅.

sno*_*ete 19

在您的可观察链中添加过滤器运算符.您可以明确过滤空值,或只检查您的用户是否真实 - 您必须根据需要进行调用.

仅过滤掉空用户:

public currentUser = this.currentUserSubject
                         .asObservable()
                         .filter(user => user !== null)
                         .distinctUntilChanged(); 
Run Code Online (Sandbox Code Playgroud)


Ami*_*noy 17

使用rxjs@6和打字稿推荐的(可读/可维护)方式是定义以下类型保护:

export function isNonNull<T>(value: T): value is NonNullable<T> {
  return value != null;
}
Run Code Online (Sandbox Code Playgroud)

并用pipe和扩充主题filter

subject.pipe(filter(isNonNull))
Run Code Online (Sandbox Code Playgroud)

  • NonNullable 类型指的是 null 或未定义,而不仅仅是 null。如果您想允许未定义的值(这不是人们通常想要的),您需要将检查替换为 !== null 并将 NonNullable 替换为:`type NotNull&lt;T&gt; = T extends null ? 从来没有:T;` (2认同)

ack*_*ser 14

Anoter检查值的方法存在

public currentUser = this.currentUserSubject
                         .asObservable()
                         .filter(Boolean)
                         .distinctUntilChanged(); 
Run Code Online (Sandbox Code Playgroud)

  • 你会失去类型接口,rxjs 6.5 会抱怨未知类型 (7认同)
  • @ ShacharHar-Shuv他不在这里使用`new`,所以它只是执行类型转换。参见此处:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/布尔值等于!! 但在这种情况下,它更具可读性,因为我们不必引入lambda (3认同)
  • 要修复您需要的所有内容,例如 filter&lt;number&gt;(Boolean) (2认同)

Wil*_*ilt 6

这很简单:

filter(user => !!user),
Run Code Online (Sandbox Code Playgroud)

如果用户评估为 false,则不会通过过滤器。

所以会过滤这些假值(链接到 MDN 上的 Falsy)