【问题标题】:Rxjs Subscription triggers more than onceRxjs 订阅触发不止一次
【发布时间】:2019-02-15 18:18:50
【问题描述】:

我的订阅被多次触发非常神秘 - 我不知道我的错误是什么 - 我在另一个上采用了相同的方法,但它不会被触发多次

 @Injectable({
  providedIn: 'root'
})
export class CommonService {

  constructor() {
    this.getpatientId = this.bindPatientId.asObservable();
  }

  bindPatientId: Subject<number> = new Subject<number>();
  getpatientId: Observable<number>;

  setPatientId(patientId: number) {
    this.bindPatientId.next(patientId);
  }

  bindTabId: Subject<number> = new Subject<number>();
}

Subject设置新值

 toggleProfile(patientId: number) {
    this.commonService.setPatientId(patientId);
    this.route.navigate(['/endrolPatient']);
  }

从另一个组件监听

ngOnInit() {
    this._common.getpatientId.subscribe(
      (res) => {
        this.patientID = res;
        console.log("console inside observable", this.patientID);
      });
}

在我的控制台中,当我通过 123 - 我得到 console inside observable 123 但在第一个观察者休息后,所有订阅都翻倍并在我的控制台中登录两次 - 请帮助我修复它

【问题讨论】:

  • after the first observer rest 是什么意思?还请提供一些关于如何创建组件(从服务订阅 observable)的见解(代码)
  • 如果我向subject 添加新值,观察者会被多次触发值,但对于第一次更改它只会触发一次

标签: angular typescript rxjs angular-services


【解决方案1】:

这可能是因为您的组件正在被销毁并再次创建。因此,当您的组件销毁时,您必须销毁所有订阅。你可以在ngOnDestroy生命周期方法中做到这一点

代码:

class MyComponent implements OnInit, OnDestroy {

private sub: Subscription;

ngOnInit() {
    this.sub = this._common.getpatientId.subscribe(
      (res) => {
        this.patientID = res;
        console.log("console inside observable", this.patientID);
      });
}

ngOnDestroy(){
   this.sub.unsubscribe():
}

【讨论】:

  • 不,它被取消订阅,甚至没有触发任何价值 - 在您的解决方案之后
  • 在我的解决方案之后它没有触发任何价值?这意味着什么?我只解释了如何在不使用时终止订阅并避免每次访问组件时多次订阅。这与停止触发值无关。
  • 是的,但我的经验是没有一个观察者收到任何数据
  • 嗯,这就是问题所在。你试过ReplaySubject(1)BehaviorSubject 吗?他们都应该工作。因为您正在订阅一个已经发出值的可观察对象。
  • 我试过BehaviourSubject 我会试试ReplaySubject() 让你知道
【解决方案2】:

每当您将主题用于所有事情时都使用行为主题!,我前段时间也遇到过这个问题,但这对我有用!

 bindPatientId: Subject<number> = new BehaviourSubject<number>();
 bindTabId: Subject<number> = new BehaviourSubject<number>();

订阅时,它返回主题的最后一个值。常规的 observable 只有在收到 onnext 时才会触发 你也可以使用

import { take } from 'rxjs/operators';

然后添加

.pipe(
  take(1)

在订阅之前

看这里 https://www.learnrxjs.io/operators/filtering/take.html

希望对你有帮助!

【讨论】:

  • 不,如果它是BehaviourSubject,我需要为其初始化一个默认值——我不想这样做,而且如果我这样做,结果是一样的——是的,我们可以使用@ 987654326@ 操作员,但我想知道为什么它会被多次触发
  • 好吧,我认为是因为您没有销毁它,而是在没有取消订阅的情况下订阅它。如果是这样,您可以添加 ngOndestroy 方法并在那里取消订阅
猜你喜欢
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 2018-09-05
  • 2021-12-22
  • 1970-01-01
  • 2019-09-22
  • 2022-07-11
  • 2016-08-06
相关资源
最近更新 更多