【问题标题】:Angular Observable Service being called multiple timesAngular Observable Service 被多次调用
【发布时间】:2020-08-26 03:33:53
【问题描述】:

我有一个服务,它有一个返回和可观察的方法。我有一个组件在加载时订阅该 observable。我的服务中有一个 console.log 来记录每次调用它。 当我运行我的应用程序并查看我的控制台窗口时,我看到了 3 个记录值的实例。这是为什么?我只订阅一次可观察服务。

我实际上有一个比这个简单示例更广泛的问题,我注意到当我有多个订阅我的服务时,我会收到更多重复调用我的函数和服务。为什么会发生这种情况,因为我的假设是使用 rxjs 和主题的目的是拥有某种基本形式的状态管理,并且其目的是避免检索未更改的数据。

服务:

export class ResultService {

  protected id;
  private results$ = new Subject<any>();
  
  constructor(
    private dataService: DataService, 
  ) { }

  getResults(id): Observable<any> {
    console.log('get result called in ResultService');
    this.dataService.getResults(id)
      .subscribe(res => {
        console.log('the value of res in ResultService constructor');
        this.results$.next(res);
      })
    return this.results$.asObservable();
  }
}

结果组件

private subscription$;
@Input() id;

  constructor(
       this.subscription$ = this.resultService.getResults(this.competitionId);
       this.fetchResults(this.competitionId);
  ) { }

  ngOnInit() {
    this.fetchResults(this.id);
  }
  fetchResults(id){
    this.resultService.getResults(this.id)
      .subscribe((data) => 
      {
        data.forEach(resultElement => {
           //do something
        });
        this.resultList = data;
      })
  }
  ngOnChanges() {
    this.fetchResults(this.id);
  }

  ngOnDestroy() {
    this.subscription$.unsubscribe(); //unsubscribe
  }

摘要页面 html 文件 - 将结果组件作为它传递 id 的子组件

  <ion-col size-lg="5">
    <ion-row>
      <ion-col>
        <app-results-component [id]="id"></app-results-component>
      </ion-col>
    </ion-row>
  </ion-col>

摘要页面 ts 文件

  private id: number;
  private dataSub$;
  private resultData : any;

  ngOnInit() {
    this.activatedRoute.params.subscribe(params => {
      this.competitionId = params['id'];
      this.getData(this.id);
    }
  }

  getData(id) {
    this.dataSub$ = this.resultService.getResults(id);
    this.dataSub$
    .subscribe((data) => {
        this.resultData = data;
        this.dosomething(this.resultData);
      })
  }

  ngOnDestroy() {
    this.dataSub$.unsubscribe(); //unsubscribe
  }

【问题讨论】:

  • 我认为问题出在 ngOnChanges() 只是一段时间,你能从 ngOnChanges() 中删除 this.fetchResults(this.id) 并检查它被调用了多少次吗?
  • 为什么要调用onChanges中的方法?
  • 是的@SivakumarTadisetti,你是对的。当我评论它时,我只接到一个电话。事实上,它还减少了调用该服务的其他组件中的调用次数。为什么是这样?我最初使用更改是因为我没有使用主题。当我有新的更改时,我需要修改我的代码以调用 next 以便订阅者发出和接收新值。
  • new changes -> 您是否只需要在ngOnChagnes 中调用this.fetchResults(this.id) 来更改一个@input() 值?如果正确,您需要有条件检查输入的currentvaluepreviousvalue
  • 你能用@inputs() 更新这个问题,并且可以告诉你接下来要调用哪个输入变化吗?

标签: angular rxjs


【解决方案1】:

您必须取消订阅。

示例代码:

constructor(
    private resultService: ResultService
  ) { }

  subscription$ //declare

  ngOnInit() {
    this.fetchResults(this.id);
  }

  fetchResults(id){
    this.subscription$ = this.resultService.getResults(this.id)
      .subscribe((data) => 
      {
        data.forEach(resultElement => {
           //do something
        });
        this.resultList = data;
      })
  }

  ngOnChanges() {
    this.fetchResults(this.id);
  }

  ngOnDestroy() {
    this.subscription$.unsubscribe() //unsubscribe
  }
}

【讨论】:

  • 我进行了更改,但根据我在 console.log 中看到的内容,我仍然接到三个电话。
【解决方案2】:
  • 需要添加if条件if (changes.id)

  • 好像不用在onInit中调用

  • 你需要取消订阅 observable

     private unSub = new Subject();
    
     constructor(
         private resultService: ResultService
     ) { }
    
     fetchResults(id){
         this.resultService.getResults(this.id)
             .pipe(
                 takeUntil(this.unSub)
             )
             .subscribe((data) =>
             {
                 data.forEach(resultElement => {
                     //do something
                 });
                 this.resultList = data;
             })
     }
     ngOnChanges(changes: SimpleChanges) {
         if (changes.id) {
             this.fetchResults(this.id);
         }
     }
    
     ngOnDestroy(): void {
         this.unSub.next();
         this.unSub.complete();
     }
    

【讨论】:

    猜你喜欢
    • 2023-03-04
    • 1970-01-01
    • 2017-12-06
    • 2019-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-03
    • 1970-01-01
    • 2021-12-22
    相关资源
    最近更新 更多