【问题标题】:RxJS subscription not firingRxJS 订阅未触发
【发布时间】:2019-06-05 23:51:47
【问题描述】:

目前正在学习 RxJS。我在一个服务中有一个整数selectedCourseIndex,我想要一个单独的组件来订阅。

courses-section.service.ts

private selectedCourseIndex: number = -1; //this number can change from another method
private selectedCourseIndexUpdated = new Subject<number>();

getSelectedCourseUpdateListener(){
    return this.selectedCourseIndexUpdated.asObservable();
}

courses-section.component.ts

  private selectedCourseIndex: number = -1; //Placeholder initial selectedCourseIndex until new one given on init from courses-section service
  private selectedCourseSub: Subscription;

  constructor( public coursesSectionService: CoursesSectionService ){}

  ngOnInit(){
   this.selectedCourseIndex = 
   this.coursesSectionService.getSelectedCourseIndex();
   this.selectedCourseSub = this.coursesSectionService
    .getSelectedCourseUpdateListener()
    .subscribe((selectedCourseIndex: number) => {
      this.selectedCourseIndex = selectedCourseIndex;
      console.log('this fires when subscription updates'); //this never fires once
    });
  }

但是,无论是在最初订阅时还是在整数更改时,订阅都不会触发。怎么了?

【问题讨论】:

    标签: angular rxjs


    【解决方案1】:

    “Subject” observable 不会在订阅时重播之前的值。仅当您在服务中执行以下操作 [以某种方式] 时,您的订阅才会触发 -

    this.selectedCourseIndexUpdated.next(<your new number>);
    

    要在每个订阅上触发订阅 [获取最后发出的值],您应该使用“BehaviorSubject”而不是像这样的主题 -

    private selectedCourseIndexUpdated = new BehaviorSubject<number>(0);
    

    BehaviorSubject 重播每个订阅上最后发出的值。注意 BehaviorSubject 构造函数采用默认值。

    【讨论】:

    • 我认为主题 observables 的目的是将其当前值发送给订阅的任何人?
    • "subsrcibe" 到 "Subject" 将接收订阅后发出的所有值。而 BehaviorSubject 总是在每个新订阅上发出最后一个值。参考 - rxjs-dev.firebaseapp.com/guide/subject#subjectrxjs-dev.firebaseapp.com/guide/subject#behaviorsubject
    • 当然,但是我的主题订阅在订阅后甚至没有收到新值。当 selectedCourseIndex 发生变化时,没有 console.log
    • 你的意思是从这一行 - this.selectedCourseIndex = selectedCourseIndex;?如果是,那么分配新值是不够的。您需要执行“this.selectedCourseIndexUpdated.next()”。您可以执行以下操作 - 在您的服务中有一个名为“updateIndex(newIndex) { this.selectedCourseIndex = newIndex; this.selectedCourseIndexUpdated.next(newIndex);}”的方法。从要更新索引的位置调用此函数。请注意,如果您从 subscribe() 调用,这将导致递归。
    • 但是当 selectedCourseIndex 发生变化时,为什么我当前订阅中的任何内容都没有触发?
    【解决方案2】:

    如果我错了,请纠正我,

    您的问题:您想要一个可观察对象的当前(或最新)值,而不管是否有人现在发出了一个值。

    回答: SubjectObservable 没有当前值。当一个值被发出时,它被传递给订阅者,并且 observable 完成了它。 Observable 只有在向主题流发出另一个值时才会起作用。

    如果您想获得当前值,请使用专为您需要的目的而设计的 BehaviorSubject,它会保留最后发出的值,无论何时发出并立即将其传达给新的订阅者。

    注意:它还有一个方法 getValue() 来获取当前值。


    您面临的另一个问题。

    问题:您当前的代码似乎不起作用。

    回答: 让我举个例子说明我如何使用 Observable -

    Courses-action.service.ts

    import { Injectable } from ‘@angular/core’;
    import { Subject } from ‘rxjs’;
    
    @Injectable()
    Export class CoursesActionService {
      Public selectedCourseIndexUpdated = new Subject<any>();
      Public isCourseIndexUpdated$ = this.selectedCourseIndexUpdated.asObservable();
    
    Public announceSelectedCourseIndex(response: any) {
      this.selectedCourseIndexUpdated.next(response);
    }
    

    一些向订阅者发出值的随机文件 -

    this.coursesActionService.announceSelectedCourseIndex(453);
    

    监听发射值的一些随机文件 -

    this.coursesActionService.isCourseIndexUpdated$.pipe(takeUntil(this.destroyed$))
    .subscribe(res => console.log(‘i have the response’, res));
    

    【讨论】:

    • 为什么我们必须将 Subject 强制转换为 Observable?为什么我们不能直接订阅 observable?
    • @ColbyBoren 您的问题需要我解释可观察对象的工作原理以及主题在其中扮演什么角色。什么是多播和单播。为此,让我将您引导至适当的资源 - medium.com/@luukgruijs/understanding-rxjs-subjects-339428a1815b 我认为此链接足以让您对主题及其在 observables 中的作用有一个基本的了解。
    猜你喜欢
    • 1970-01-01
    • 2016-08-06
    • 2023-03-12
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 2022-07-11
    • 2019-09-24
    相关资源
    最近更新 更多