gpt4 book ai didi

rxjs - 用于组合 RxJS Observables 的 bool 代数助手

转载 作者:行者123 更新时间:2023-12-05 02:13:38 25 4
gpt4 key购买 nike

如何避免编写疯狂的 combineLatest 语句来计算简单的 bool 逻辑表达式?

例如。这个简单的表达式几乎不适合 stackoverflow 代码控制,如果你不小心重新排序参数,你将很难调试!

this.showPlayButton = combineLatest(this.playPending, this.isReady, this.showOverlay)
.pipe(
map(([playPending, isReady, showOverlay]) => isReady && !playPending && showOverlay),
distinctUntilChanged();

最佳答案

好吧,我很惊讶我找不到一个现有的库,所以我开始收集一些 helper observable 创建函数。

Observable<boolean>助手

这些是“最纯粹的”助手,接收并输出 Observable<boolean> .我添加了 distinctUntilChanged()到每个,这可以防止多次不必要的排放。这是一个非常惰性的运算符,没有 share 的更复杂结果。或 shareReplay(1) - 但重要的是要知道它已被应用。

export const allTrue = (...observables: Array<ObservableInput<boolean>> ) => combineLatest(observables).pipe(map(values => values.every(v => v == true) ), distinctUntilChanged());
export const allFalse = (...observables: Array<ObservableInput<boolean>> ) => combineLatest(observables).pipe(map(values => values.every(v => v == false) ), distinctUntilChanged());
export const anyTrue = (...observables: Array<ObservableInput<boolean>> ) => combineLatest(observables).pipe(map(values => values.find(v => v == true) != undefined ), distinctUntilChanged());
export const anyFalse = (...observables: Array<ObservableInput<boolean>> ) => combineLatest(observables).pipe(map(values => values.find(v => v == false) != undefined), distinctUntilChanged());

export const not = (observable: Observable<boolean> ) => observable.pipe(map(value => !value), distinctUntilChanged());

真值/假值的 bool 转换器

同一类别中的其他一些“ helper ”,例如ifTruthyifFalsy旨在与上述助手一起使用(因为它们需要真正的 bool 值)。这些当前使用 !=而不是 !== , 所以 isDefined(of(null))isDefined(of(undefined))两个产品一个true可观察的。还有 isEqual不会进行深度比较。

 export const isTruthy = <T>(observable: Observable<T>) => observable.pipe(map(obsValue => !!obsValue), distinctUntilChanged());
export const isFalsey = <T>(observable: Observable<T>) => observable.pipe(map(obsValue => !obsValue), distinctUntilChanged());

export const isDefined = <T>(observable: Observable<T>) => observable.pipe(map(obsValue => obsValue != undefined), distinctUntilChanged());
export const isEqual = <T>(observable: Observable<T>, value: T) => observable.pipe(map(obsValue => obsValue == value), distinctUntilChanged());
export const notEqual = <T>(observable: Observable<T>, value: T) => observable.pipe(map(obsValue => obsValue != value), distinctUntilChanged());

还有第三类,例如iff这相当于 SQL Server 的 iff 声明。这些的输出是 AB (无论您的参数是什么类型)。这就像一个非常简单的 if 语句。

export const iff = <A, B>(ifObs: Observable<boolean>, trueValue: A, falseValue: B) => ifObs.pipe(map(value => value ? trueValue : falseValue));

组成

使用 RxJS 可以非常容易地将它们组合在一起并创建非常可读的组合。我经常在 Angular 组件中将它们用于 UI 特定属性,并且更容易调试。以下是真实的代码示例,应该很容易理解。

loading$ = not(this.loaded$);
hasSelectedOrder$ = isTruthy(orderId$); // Note: this wouldn't work for something zero
hasSelectedOrder$ = isDefined(orderId$); // uses != undefined

layout$ = iff(deviceType.isDesktop$, 'horizontal', 'vertical');
isMobileOrTablet$: anyTrue(this.isMobile$, this.isTablet);
isTabletOrDesktop$: anyTrue(this.isTablet, this.isDesktop$);

isBusy$ = anyTrue(this.hasBusyTask$, this.busyService.isBusy$);

// very useful for UI (using async pipe)
isAddNewCreditCardSelected$ = isEqual(selectedPaymentMoniker$, 'NEW');
showSavedPayments$ = allTrue(showAvailablePaymentMethods$, hasVault$, not(isAddNewCreditCardSelected$));
showAddCreditCardButton$ = allTrue(showPaymentButtons$, not(showAddCreditCardPanel$), not(showVault$))
showDefaultFooter$ = allTrue(not(this.isWebapp$), this.showDefaultFooter$);
showBusyIndicator$ = allTrue(not(this.pageService.handlesBusyIndicator$), this.busyService.isBusy$) ;

至于原来的问题,就变成了这样:

this.showPlayButton$ = allTrue(this.isReady$, not(this.playPending$), this.showOverlay$)

当我想出新的时,我会添加到这个列表中。这些已经涵盖了我迄今为止遇到的大多数情况。这当然可以变成一个图书馆,但我现在无法将其正式化以能够做到这一点。如果已经存在的东西很乐意比较:-)

关于rxjs - 用于组合 RxJS Observables 的 bool 代数助手,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54834720/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com