gpt4 book ai didi

angular - 在 RXJS 中,您可以在重新发送之前处理传递给 subject.next() 的数据吗?

转载 作者:行者123 更新时间:2023-12-05 04:31:30 26 4
gpt4 key购买 nike

我有一种感觉,这个问题将暴露我对可观察量的理解的一些严重的天真,但冒着看起来很愚蠢的风险让我还是问吧。

我想创建一个 RXJS 主题,它在重新发送之前对传递给它的数据进行一些操作。让我用一个简单的例子来简单地解释一下。

例如将 distinctUntilChanged 滚动到源 observable

在下面的代码中,我有一个可观察对象,它会在每次发生可能改变窗口的 active 状态的事件时更新。

然而,为了避免发出重复值,我有第二个可观察对象,它在发出它们之前仅过滤不同的值。


export class MyService {
activeValue$ = new Subject<boolean>()
active$: Observable<boolean>

constructor() {

// setup an observable that only emits *changed*
// values of the active value
this.active$ = this.activeValue$.pipe(
distinctUntilChanged()
)

// Listen to multiple cues for things that might alter active state
window?.addEventListener('focus', () => this.setActiveValue(true))
window?.addEventListener('click', () => this.setActiveValue(true))
window?.addEventListener('hide', () => this.setActiveValue(false))
window?.addEventListener('blur', () => this.setActiveValue(false))

}
}

我可以将两个 observable 组合成一个 observable 吗?

这个例子简单到微不足道,但它说明了目标,即在重新发送数据之前,通过 .next() 预处理进入可观察对象的数据。

理想情况下,我希望能够编写如下代码:


export class MyService {

active$: Subject<boolean>

constructor() {

// This (for many reasons) doesn't work but it kind of shows what
// I'm hoping for...
this.active$ = new Subject<boolean>().pipe(
distinctUntilChanged()
)
...

}
}

最佳答案

您在第一个示例代码中所做的是实现此目的的典型方法:

  • 定义一个私有(private)主题来插入值(value)
  • 剥离一个公共(public)可观察对象以应用任何“清理”逻辑
  • 消费者访问公众可观察到的“清洁”排放物

Can I combine the two observables into a single observable?

从您想要的代码:

    this.active$ = new Subject<boolean>().pipe(
distinctUntilChanged()
)

这可能行得通...但是,您没有维护对主题的引用,因此您无法推送值 (subject.next())。所以你确实需要一个 subject 和一个 observable。

你可能会发现在构造函数之外初始化你的可观察对象更干净,就像你对你的主题所做的那样:

export class MyService {
private activeValue$ = new Subject<boolean>()
public active$ = this.activeValue$.pipe(distinctUntilChanged())

constructor() {
// Listen to multiple cues for things that might alter active state
window?.addEventListener('focus', () => this.setActiveValue(true))
window?.addEventListener('click', () => this.setActiveValue(true))
window?.addEventListener('hide', () => this.setActiveValue(false))
window?.addEventListener('blur', () => this.setActiveValue(false))
}

setActiveValue(value: boolean) {
this.activeValue$.next(value)
}
}

现在...以上假设您实际上需要一个主题来“手动”推送值。如果您可以通过其他可观察对象获取事件,则根本不需要主题。在事件的情况下,您可以选择使用 fromEvent :

export class MyService {

public active$ = merge(
fromEvent(window, 'focus').pipe(mapTo(true)),
fromEvent(window, 'click').pipe(mapTo(true)),
fromEvent(window, 'hide').pipe(mapTo(false)),
fromEvent(window, 'blur').pipe(mapTo(false)),
).pipe(
distinctUntilChanged(),
shareReplay(1) // add this if you want subscribers to receive the
) // most recent emission upon subscription which
// is often desired in angular services
}

关于angular - 在 RXJS 中,您可以在重新发送之前处理传递给 subject.next() 的数据吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71840192/

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