是否有特定的习惯用法或实用程序用于undefined
从 RxJS observables 中过滤?此代码具有我想要的行为:
obs.pipe(filter(x => x !== undefined))
Run Code Online (Sandbox Code Playgroud)
一些替代方案是
obs.pipe(filter(x => x)) // for all falsy values
obs.pipe(filter(Boolean)) // for falsy variables using Boolean ctor
Run Code Online (Sandbox Code Playgroud)
小智 20
严格来说,单独使用过滤器来删除未定义的值并不能满足您的所有需求。它过滤掉未定义的值,但不会更改类型以指示未定义不再是可能的值。
在示例中:
const obs = new Subject<string | undefined>;
const stringObs = obs.pipe(filter(x => x !== undefined))
Run Code Online (Sandbox Code Playgroud)
在stringObs
观察到的仍然有型Observable<string | undefined>
。
要解决此问题,您需要使用:
const stringObs = obs.pipe(filter(x => x !== undefined) as OperatorFunction<string | undefined, string>)
Run Code Online (Sandbox Code Playgroud)
如果您使用严格的空检查,这只是一个真正的问题,但是如果您这样做(并且可以说您应该这样做),那么创建自定义运算符突然变得更有意义!就像是
function filterNullish<T>(): UnaryFunction<Observable<T | null | undefined>, Observable<T>> {
return pipe(
filter(x => x != null) as OperatorFunction<T | null | undefined, T>
);
}
Run Code Online (Sandbox Code Playgroud)
做这项工作。
然后您可以使用:
const stringObs = obs.pipe(filterNullish())
Run Code Online (Sandbox Code Playgroud)
和stringObs
will的类型Observable<string>
。Typescript 能够T
正确推断出类型给我留下了深刻的印象。
为了帮助打字稿理解未定义的值已被删除,一种方法是创建一个自定义 operator。另一种方法是通过用户定义的类型保护。
function isDefined<T>(arg: T | null | undefined): arg is T {
return arg !== null && arg !== undefined;
}
const obs = from(['hello', null, undefined]);
const filtered: Observable<string> = obs.pipe(filter(isDefined));
Run Code Online (Sandbox Code Playgroud)
Rxjs 运算符被认为是低级的,旨在以可读的方式组合以创建可预测使用的结果可观察值。让一个“实用程序”为你做这件事并不完全是我(谦虚地)所说的“rxjs 方式”。如果您所说的“惯用语”是指约定,那么您的代码示例基本上就是您要寻找的内容。
我自己定期使用精确的过滤器模式,以至于我考虑过创建一个自定义运算符;然而,而不是这个:
obs.pipe(filter(x => x !== undefined))
Run Code Online (Sandbox Code Playgroud)
你最终会得到这样的结果:
obs.pipe(notUndefined()) // or hasValue() or whatever you want to name it...
Run Code Online (Sandbox Code Playgroud)
这里没有太多积蓄。我认为你甚至没有在可读性上得到节省(或者说完全是边缘性的),这就是为什么我从来没有抽出时间来考虑它。不对此进行动员的另一个理由是,过滤布尔值也很常见,这会让您开始怀疑是否应该将两者结合起来,以避免出现太多令人困惑/类似的运算符,所有这些都可以轻松创建filter
无论如何使用等等等等......
长话短说,我对这个确切的问题思考了很多,并且认为您只需使用您提供的代码示例即可。这是正确的”。它是“rx-js-y”。它是可读的。
归档时间: |
|
查看次数: |
6197 次 |
最近记录: |