Angular RxJs运营商使用循环避免多个订阅

Angular RxJs运营商使用循环避免多个订阅,angular,typescript,rxjs,rxjs-observables,Angular,Typescript,Rxjs,Rxjs Observables,我正在为Angular应用程序编写导航组件。我有以下代码。我希望避免多重订阅反模式。我正在努力学习RxJs语法,以及该走哪条路(forkJoin、mergeMap等) 如何重构这些,以删除订阅中的订阅 以下是我所拥有的,目前有效,但在订阅中有一个订阅: @Component({ selector: 'ehrcc-nav', templateUrl: './nav.component.html', styleUrls: ['./nav.component.css'] }) export

我正在为Angular应用程序编写导航组件。我有以下代码。我希望避免多重订阅反模式。我正在努力学习RxJs语法,以及该走哪条路(forkJoin、mergeMap等)

如何重构这些,以删除订阅中的订阅

以下是我所拥有的,目前有效,但在订阅中有一个订阅:

@Component({
  selector: 'ehrcc-nav',
  templateUrl: './nav.component.html',
  styleUrls: ['./nav.component.css']
})
export class NavComponent implements OnInit {

  applicationName: string = 'AppName';
  userDisplayName: string = '';
  isAuthorizedUser: boolean = false;
  isAdminUser: boolean = false;

  groupsList: MemberGroup[] = [];

  constructor(private userService:UserService,
    private auditService: UserAuditService,
    private router: Router) { }

  ngOnInit() {

    this.getDisplayName();

    this.userService.getGroupMembershipsForUser().subscribe(members =>{
      this.groupsList = members;
      for (let g of this.groupsList){
        if (g.id === this.userService.usersGroupId){
          this.isAuthorizedUser = true;
          this.router.navigate(['/workItem']);
        }
        if (g.id === this.userService.adminGroupId){
          this.isAdminUser = true;
        }
      }
      this.logUserInfo();   <---- ANTI-PATTERN
     });

  }

  getDisplayName(){
    this.userService.getSignedInAzureADUser().subscribe(
      (user) => this.userDisplayName = user.displayName,
      (error: any) => {
        return console.log(' Error: ' + JSON.stringify(<any>error));
    });
  }

  logUserInfo(){
    var audit = new UserAudit();
    audit.Application = this.applicationName;
    audit.Environment = "UI";
    audit.EventType= "Authorization";
    audit.UserId = this.userDisplayName;
    audit.Details = ` User Is Authorized: ${this.isAuthorizedUser}, User Is Admin: ${this.isAdminUser}`;

    this.auditService.logUserInfo(audit)
    .subscribe({ 
      next: (id)=> console.log('Id created: '+ id),
      error: (error: any) => console.log(' Error: ' + JSON.stringify(<any>error) )
    });
  }
}

@组件({
选择器:“ehrcc导航”,
templateUrl:'./nav.component.html',
样式URL:['./nav.component.css']
})
导出类NavComponent实现OnInit{
applicationName:string='AppName';
userDisplayName:string='';
isAuthorizedUser:boolean=false;
isAdminUser:boolean=false;
groupsList:MemberGroup[]=[];
构造函数(私有用户服务:用户服务,
私有auditService:UserAuditService,
专用路由器:路由器{}
恩戈尼尼特(){
这个.getDisplayName();
this.userService.getGroupMembershipsForUser().subscribe(成员=>{
this.groupsList=成员;
for(让g表示这个。groupsList){
if(g.id==this.userService.usersGroupId){
this.isAuthorizedUser=true;
this.router.navigate(['/workItem']);
}
if(g.id==this.userService.adminGroupId){
this.isAdminUser=true;
}
}
this.logUserInfo();this.userDisplayName=user.displayName,
(错误:any)=>{
返回console.log('Error:'+JSON.stringify(Error));
});
}
logUserInfo(){
var audit=new UserAudit();
audit.Application=this.applicationName;
audit.Environment=“UI”;
audit.EventType=“授权”;
audit.UserId=this.userDisplayName;
audit.Details=`用户已授权:${this.isAuthorizedUser},用户是管理员:${this.isadmin}`;
this.auditService.logUserInfo(审计)
.subscribe({
下一步:(id)=>console.log('id created:'+id),
错误:(error:any)=>console.log('error:'+JSON.stringify(error))
});
}
}
您可以使用forkJoin


一旦你订阅了forkJoin,你将得到一个包含所有值的对象,你可以从中调用logUserInfo,所有的可观察对象都需要完成()为了发出forkJoin,我发现了这个问题,因为我正在搜索为什么一些
subscribe
代码块在没有明显原因的情况下被多次执行

我发现这是由于服务返回了一些未加载正确数据的可观察数据。因此,我用解决了这个问题,其中:

忽略
持续时间
毫秒的源值,然后从可观察的源中发出最近的值

因此,使用问题代码,可以使用该运算符添加一个

import { auditTime, ... } from 'rxjs/operators';

this.userService.getGroupMembershipsForUser().
 .pipe(auditTime(1E3)) // delays for 1 second and gets the most recent value
 .subscribe(members => { ... });

为什么不在Observable中使用map操作符并发出修改后的数据?可以发布源Observable吗?我个人建议使用ngrx Statemanagement来完成此类任务。链接操作比连接响应容易得多。当然,测试它们更容易。@Robertgarcia我发布了源Observable,或者我所做的我想你的意思是当你询问可观测的源时。它显示了我必须做什么才能从另一个API中获取原始数据。@MoxxiManagarm谢谢你的评论。我没有使用你所说的技术。可能是重复的
import { auditTime, ... } from 'rxjs/operators';

this.userService.getGroupMembershipsForUser().
 .pipe(auditTime(1E3)) // delays for 1 second and gets the most recent value
 .subscribe(members => { ... });