【问题标题】:Angular - async/await Observable toPromise update broadcast new BehaviorSubject data return PromiseAngular - async/await Observable toPromise 更新广播新的 BehaviorSubject 数据返回 Promise
【发布时间】:2021-01-16 05:08:46
【问题描述】:

我有一个项目,其中包含我继承的这段代码,在我的一生中,我无法理解到底发生了什么,并且教师资料存在一些错误,所以我试图弄清楚开发人员可能有什么一直在努力做。如果可以,请帮助查看并提供您看到的任何提示或问题。我想让这段代码遵循最佳实践,并希望为接下来的人记录如何做到这一点。

所以我的问题是:

  1. 在每次调用 getTeacherProfile()、getTeacherProfileInfo()、getTeacherProfileByProfileId() 时创建一个新的 BehaviorSubject 是否有意义,因为这不会创建一个新变量并且不会通知任何以前的订阅?

  2. 正确的最佳模式是在构造函数中初始化一次吗

this.broadCast = new BehaviorSubject<TeacherProfileModel>();

然后在每个想要更新、推送、发送任何新数据的方法内部调用:

this.broadCast.next(data);
  1. 不是在 Promise .then() 的 getter 方法中进行订阅,而是在组件生命周期中一次性从 ngOnInit() 中生成所有 .subscribe((data) => { 不是标准做法吗? ?

  2. 也没有 ngOnDestroy() 或取消订阅,我认为这是订阅任何 BehaviorSubject 时的标准做法,因为如果不这样做会造成内存泄漏和意外结果?

  3. 这可能是由于相关代码调用方法的顺序导致订阅 BehaviorSubjects 的依赖代码产生不一致的用户体验,这些代码可能被更改/重新分配和忘记,从而导致意外和不可预测的结果?

提前感谢您的帮助!

代码摘录

teacher.service.ts

  async getTeacherProfile(): Promise<TeacherProfileModel> {
    if (this.teacherProfileId > 0) {
      var data = await this.crudService.get<TeacherProfileModel>("/tProfile/GetTeacherProfileData",
        new HttpParams().set('teacherProfileId', this.teacherProfileId.toString())).toPromise();
      this.broadCast = new BehaviorSubject<TeacherProfileModel>(data);
      this.teacherProfile = data;
      this.personalizedURL = this.teacherProfile.PersonalizedUrl;
    }
    else {
      if (this.teacherProfileId === 0) {
        this.initialiseTeacherProfile();
        this.commonService.isDefaultImageFlag = true;
      }
      this.broadCast = new BehaviorSubject<TeacherProfileModel>(this.teacherProfileData);
    }

    return this.teacherProfile;
}

async getTeacherProfileInfo(url: string): Promise<TeacherProfileModel> {
    var data = await this.crudService.get<TeacherProfileModel>("/teacherProfile/GetTeacherProfileInfo",
      new HttpParams().set('personlizedUrl', url)).toPromise();
    this.broadCast = new BehaviorSubject<TeacherProfileModel>(data);
    this.teacherProfile = data;
    this.personalizedURL = this.teacherProfile.PersonalizedUrl;
    return this.teacherProfile;
} 

async getTeacherProfileByProfileId(teacherProfileId:any): Promise<TeacherProfileModel> {
    this.teacherProfileId = teacherProfileId;
    this.imageUrl = localStorage.getItem("userImageUrl");
  
    var data = await this.crudService.get<TeacherProfileModel>("/teacherProfile/GetTeacherProfileData",
      new HttpParams().set('teacherProfileId', this.teacherProfileId.toString())).toPromise();
    this.broadCast = new BehaviorSubject<TeacherProfileModel>(data);
    this.teacherProfile = data;
    this.personalizedURL = this.teacherProfile.PersonalizedUrl;
    return this.teacherProfile;
}

profile.component.ts

ngOnInit() {
    this.teacherService.getTeacherProfile().then((response: any) => {
         this.teacherService.broadCast.subscribe(data => {
              if(data !== undefined) { 
                   //do something  
              }
         });
    });
}

teacher-profile-edit.component.ts


  previewChanges() {
    this.commonService.userProfilePic = localStorage.getItem('userImageUrl');
    this.commonService.isStudentUser = false;
    this.teacherService.broadCast.next(this.teacherProfile);
  }


  private getTeacherProfileData() {
    this.teacherService.getTeacherProfile().then((response: any) => {
      this.teacherService.broadCast.subscribe(data => {
        if(data !== undefined) {
          this.teacherProfile = data;
          this.onProfileStatusChange(this.teacherProfile.IsProfileStatusPrivate);
          this.shortIntroLength = this.introLength - data.ShortIntroduction.length;
          if (data.TeacherQualifications.length === 0) {
            this.addQualification();
          }
        } else {
          var err = 'Error'; this.toastr.error('Oops! Something went wrong! '+err); throw err;
        }
      });
    });
  }

【问题讨论】:

    标签: javascript angular rxjs behaviorsubject


    【解决方案1】:
    1. 首先,您不需要每次只需使用 .next(null) 方法传递 null 时都创建新的 Behavior Subject ,而且在您订阅了这个的地方,您可以设置来自 Behavior Subject 的响应不应为 null 的条件。

    2. 毫无疑问,这是使用 BehaviorSubject 的正确方法。甚至你可以结帐官方网站https://rxjs-dev.firebaseapp.com/api/index/class/BehaviorSubject

    3. 我没有得到这个,但我建议你去订阅并将所有订阅放入订阅中,并在组件销毁钩子上取消订阅。 https://medium.com/thecodecampus-knowledge/the-easiest-way-to-unsubscribe-from-observables-in-angular-5abde80a5ae3

    4. 通过 Ans 3。是的,如果你不把它放在后台工作,如果它没有被破坏。

    【讨论】:

      【解决方案2】:

      嗯,你说的都是对的,

      我认为他重新初始化的原因是由于以下代码:

      this.teacherService.getTeacherProfile().then((response: any) => {
           this.teacherService.broadCast.subscribe(data => {
                if(data !== undefined) { 
                     //do something  
                }
           });
      });
      

      getTeacherProfile() 返回Promise,然后订阅BehaviorSubect,本质上是订阅新的BehaviorSubject。当然,不应该这样做。

      假设crudService.get() 只是一个Http 调用,您可以简单地返回Observable,并且您需要的任何操作都可以通过(利用rxjs)管道并利用它来完成,例如缓存响应。

      teacherProfileModelResponseCache;
      getTeacherProfile(): Observable<TeacherProfileModel> {
          if (this.teacherProfileId > 0) {
              return this.crudService.get<TeacherProfileModel>("/tProfile/GetTeacherProfileData",
          new HttpParams().set('teacherProfileId', this.teacherProfileId.toString()))
              .pipe(
                  tap(x=>{
                      this.teacherProfileModelResponseCache = x;
                      this.personalizedURL = x.PersonalizedUrl;
                  })
              )
          }
          else {
              if (this.teacherProfileId === 0) {
                  this.initialiseTeacherProfile();
                  this.commonService.isDefaultImageFlag = true;
              }
          }
      
          return of(teacherProfileModelResponseCache);
      }
      

      在您的teacher-profile-edit.component.ts 上,您只需订阅它并执行所需的操作。

      private getTeacherProfileData() {
          this.teacherService.getTeacherProfile().subscribe(data => {
              if(data !== undefined) {
                  this.teacherProfile = data;
                  this.onProfileStatusChange(this.teacherProfile.IsProfileStatusPrivate);
                  this.shortIntroLength = this.introLength - data.ShortIntroduction.length;
                  if (data.TeacherQualifications.length === 0) {
                      this.addQualification();
                  }
              } else {
                  var err = 'Error'; this.toastr.error('Oops! Something went wrong! '+err); throw err;
              }
          });
      }
      

      【讨论】:

        猜你喜欢
        • 2017-09-11
        • 2020-02-05
        • 2017-10-21
        • 2023-03-10
        • 2019-05-08
        • 2018-03-27
        • 2020-11-19
        • 2018-02-05
        相关资源
        最近更新 更多