我如何增加a<数字>重录的价值?

发布于 2025-02-13 18:35:45 字数 537 浏览 1 评论 0原文

我正在使用chativioursubject,但我发现很难增加或减少

我要么创建一个无限循环的数字:

this.observer.pointsCollected$.subscribe(val => this.observer.pointsCollected$.next(val + 10));

或者我只使用一个更新,使用:

this.observer.pointsCollected$.pipe(take(1)).subscribe(val => this.observer.pointsCollected$.next(val + 10));

使用:

public pointsCollected$ = new ReplaySubject<number>();

我想 我已经使用actavionursubject并使用actabioUrsubject.getValue()解决了这个问题,

请告诉我是否这是一种好方法

I'm using a BehaviourSubject but i'm finding it difficult to increase or decrease that number

I'm either creating an infinite loop using:

this.observer.pointsCollected$.subscribe(val => this.observer.pointsCollected$.next(val + 10));

Or i'm only getting a single update using:

this.observer.pointsCollected$.pipe(take(1)).subscribe(val => this.observer.pointsCollected$.next(val + 10));

I'm creating the observable using:

public pointsCollected$ = new ReplaySubject<number>();

I think I have solved this using a BehaviourSubject instead and using BehaviourSubject.getValue()

Please let me know if this is a good approach or not

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

°如果伤别离去 2025-02-20 18:35:45

清楚定义所需的行为很重要。一个replaySubject(从可观察的意义上中)没有值,它只是一个向其订户散发值的对象。

说“ 增加一个replayubject 的值”还不够精确。

也许您想“ 发射先前发射的值增加了特定的数量

这听起来像是

要设置该设置,我们可以拥有一个发出要添加的“增量”的主题,并得出一个可观察到的发出计算值的可观察值:

increment$ = new BehaviorSubject<number>(DEFAULT_NUMBER);
  
number$ = increment$.pipe(
  scan((previous, increment) => previous + increment)
);

我们现在可以订阅number $并最初接收默认值。任何时候增量$ .next()被调用,号码$将发出上一个发行和新增量的总和。

在Angular中,您可以将其包裹在服务中,并提供公开方法来增加数字:

export class NumberService {

  private increment$ = new BehaviorSubject<number>(DEFAULT_NUMBER);
  
  public number$ = this.increment$.pipe(
    scan((previous, increment) => previous + increment)
  );

  public increaseNumber(amount: number) {
    this.increment$.next(amount);
  }

}

这是一个工作 stackblitz 演示。

It's important to clearly define the desired behavior. A ReplaySubject (in the observable sense) doesn't have a value, it's merely an object that emits values to its subscribers.

To say "increase a value of a ReplaySubject" isn't quite precise enough.

Maybe you want to "emit the previously emitted value increased by a specific amount"

This sounds like a perfect use case for the scan operator as it will emit values based on the currently received value and the prior emitted value.

To set the up we can have a Subject that emits the "increment" to be added and derive an observable that emits the calculated value:

increment$ = new BehaviorSubject<number>(DEFAULT_NUMBER);
  
number$ = increment$.pipe(
  scan((previous, increment) => previous + increment)
);

We can now subscribe to number$ and initially receive the default value. Any time increment$.next() is called, number$ will emit the sum of the previous emission and the new increment.

In Angular, you could wrap this into a service and provide a public method to increase the number:

export class NumberService {

  private increment$ = new BehaviorSubject<number>(DEFAULT_NUMBER);
  
  public number$ = this.increment$.pipe(
    scan((previous, increment) => previous + increment)
  );

  public increaseNumber(amount: number) {
    this.increment$.next(amount);
  }

}

Here's a working StackBlitz demo.

讽刺将军 2025-02-20 18:35:45
console.clear();
import { ReplaySubject } from 'rxjs';

const sub = new ReplaySubject(3);
let inc:any=0;
sub.next(1);
sub.next(9);
sub.subscribe((res) => {
  inc = inc + res;
});
console.log(inc);
  • 其他人则认为使用循环&amp;&amp; 递归功能
console.clear();
import { ReplaySubject } from 'rxjs';

const sub = new ReplaySubject(3);
let inc:any=0;
sub.next(1);
sub.next(9);
sub.subscribe((res) => {
  inc = inc + res;
});
console.log(inc);
  • Others think to use looping && Recursive Functions.
屋檐 2025-02-20 18:35:45

第一种方法是错误的,因为正如您所说,这是一个无限的循环。

我认为第二个是“增加重型对象的值”的最佳方法:它仅获得1个单个值(当前),然后仅将其递增一次。

如果您想有一个触发的“信号”,您可以将其包裹在一个主题周围:

const performIncrement$ = new Subject<number>();

performIncrement$.pipe(
  withLatestFrom(pointsCollected$),
  map(([increment, v]) => v + increment)
).subscribe(newValue => pointsCollected$.next(newValue))

// Call performIncrement$ every time you want to increment
performIncrement$.next(10)

但是我认为,最好反应地宣布可观察到可观察到,请避免尽可能多地挑战 - 首先是有点挑战 - 而不是思考“发生这种情况时,我需要将点收费的$提高到10”的命令式方式,您需要思考相反的方式”点收费$的价值是发生了多少次乘以10英寸。此示例将变成类似的内容:

const performIncrement$ = new Subject<number>();

const pointsCollected$ = performIncrement$.pipe(
  scan((acc, increment) => acc + increment, 0),
  startWith(0)
);

如果您有多个订户并且想共享相同的值,则可以使用ShareReplay(1)保留最新值 - 类似于ReplaySubject,但无需<代码> .next 它。

理想情况下,您也不会将performincrement $作为主题,这将是另一个可观察到的,只要您应该根据您的逻辑发生这种情况。

The first approach is wrong because as you said, that's an infinite loop.

The second one I think its the best way "to increase the value of a ReplaySubject": it's getting just 1 single value (the current), and then incrementing it just once.

If you want to have a "signal" that triggers that, you could just wrap it around a Subject:

const performIncrement$ = new Subject<number>();

performIncrement$.pipe(
  withLatestFrom(pointsCollected$),
  map(([increment, v]) => v + increment)
).subscribe(newValue => pointsCollected$.next(newValue))

// Call performIncrement$ every time you want to increment
performIncrement$.next(10)

But in my opinion it's better to declare observables reactively, avoid ReplaySubjects/BehaviourSubjects as much as posible - it's a bit challenging first because instead of thinking the imperative way of "when this happens I need to increase pointsCollected$ by 10" you need to think the other way around "the value of pointsCollected$ is how many times this has happened multiplied by 10". This example would become something like:

const performIncrement$ = new Subject<number>();

const pointsCollected$ = performIncrement$.pipe(
  scan((acc, increment) => acc + increment, 0),
  startWith(0)
);

If you have multiple subscribers and want to share the same value, you can use a shareReplay(1) to keep the latest value - Similar to a ReplaySubject but without having to .next on it.

And ideally you wouldn't have performIncrement$ as a Subject either, it would be another observable that emits whenever that should happen based on your logic.

旧情别恋 2025-02-20 18:35:45

我只是这样做了:

x = new BehaviorSubject(1);

increment() {
  this.x.next(this.x.value + 1);
}

I just did this:

x = new BehaviorSubject(1);

increment() {
  this.x.next(this.x.value + 1);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文