为什么 behaviorsubject 导致我的函数 运行 多次?

Why is behaviorsubject causing my function to run multiple times?

我在 Angular 中提供服务,我正在尝试创建一个 addCart 函数,该函数将参数 menuItem 添加到包含值数组的 behaviorSubject serviceCart。然后,调用 getCart,控制台记录 serviceCart 中的任何内容。

代码如下:

private serviceCart = new BehaviorSubject([]);

  initializeCart() {
    this.serviceCart.next([]);
  }

  getCart() {
    this.serviceCart.subscribe(result => console.log('SERVICECART:', result));
  }

  addCart(menuItem) {
    this.serviceCart.subscribe(result => {
      result.push(menuItem);
      this.serviceCart.next(result);
      this.getCart();
    });
  }

我希望 addCart 函数仅控制台记录数组的一个实例。但是,每当我调用 addCart 时,它都会 returns serviceCart 数组的数千个实例和错误:

ERROR RangeError: Maximum call stack size exceeded
    at SafeSubscriber.__tryOrUnsub (Subscriber.js:191)
    at SafeSubscriber.next (Subscriber.js:122)
    at Subscriber._next (Subscriber.js:72)
    at Subscriber.next (Subscriber.js:49)
    at BehaviorSubject.next (Subject.js:39)
    at BehaviorSubject.next (BehaviorSubject.js:30)
    at SafeSubscriber._next (cart.service.ts:28)
    at SafeSubscriber.__tryOrUnsub (Subscriber.js:183)
    at SafeSubscriber.next (Subscriber.js:122)
    at Subscriber._next (Subscriber.js:72)

我是 RxJs 的新手,所以任何帮助将不胜感激!

你有一个无限循环

this.serviceCart.subscribe(result => { // do on serviceCart change
      result.push(menuItem);
      this.serviceCart.next(result); // change serviceCart
      this.getCart();
});

您可能想要取消订阅:

var sub = this.serviceCart.subscribe(result => { // do on serviceCart change
      result.push(menuItem);
      sub.unsubscribe();
      this.serviceCart.next(result); // change serviceCart
      this.getCart();
});

您不应该订阅您服务中的可观察对象,订阅的应该是您服务的消费者,即组件。您不应该使用 push 改变存储在行为主体中的对象,您应该使用扩展运算符创建一个新数组。您应该使用以 $.

结尾的可观察对象的标准命名约定
serviceCart$ = new BehaviorSubject([]);

addCart(menuItem) {
  this.serviceCart$.next([...this.serviceCart$.value, menuItem]);
}

并且在您的组件中,您应该将可观察对象作为 属性 添加到组件

serviceCart$ = this.cartService.serviceCart$;

并且在您的模板中您订阅了异步管道

<ng-container *ngIf="serviceCart$ | async as serviceCart">
   // use the view variable serviceCart here which will automagically update
</ng-container>