如何解决Angular中的时间引发问题?

时间:2018-07-11 06:53:28

标签: javascript angular typescript asynchronous promise

我正在编写Angular Service以证明用户权限。在构造函数中,我想从API获取当前登录的用户。创建的当前用户可用于此服务的其他方法。从组件调用此方法以检查可以显示哪些内容,依此类推。 问题在于服务中的方法的调用速度比当前用户可用的速度快。 有可能解决这个问题吗?

permission.service.ts

@Injectable()
export class PermissionService {
  currUser = {
    'id': "",
    'permission': ""
  };
  apiService: AlfrescoApiService;
  authService: AuthenticationService;

  constructor(apiService: AlfrescoApiService, authService: AuthenticationService) {
    this.apiService = apiService;
    this.authService = authService;

    this.init();
  }

  init() {
    let userId: string = this.authService.getEcmUsername();    
    this.currUser.id = userId;

//API call
    this.apiService.sitesApi.getSiteMember(SITENAME, userId).then(resp => {
      this.currUser.permission = resp.entry.role;
    })
  }

  isSiteManager(): boolean {
    console.log(this.currUser.permission, this.currUser);
    if(this.currUser.permission === "SiteManager"){
      return true;
    }else{
      return false;
    }
  }
}

方法调用

export class AppLayoutComponent {

  constructor(permissionService:PermissionService) {
    permissionService.isSiteManager();
  }

}

在Google Chrome浏览器中输出

  

{id:“管理员”,权限:“”}
  id:“ admin”权限:“ SiteManager”

4 个答案:

答案 0 :(得分:1)

您应在getEcmUsername()中使用promise来处理此问题;之后,您可以像这样
`

this.authService.getEcmUsername().then((userID) => {
    this.apiService.sitesApi.getSiteMember(SITENAME, userId).then(resp => {
      this.currUser.permission = resp.entry.role;
    })
});

`

答案 1 :(得分:0)

我认为更好的解决方案是在此处使用Observable和rxjs。在使用中,您可以创建主题并在您的组件中订阅它,以确保数据已经存在。例如:

@Injectable()
export class PermissionService {
 public Subject<bool> userFetched= new Subject<bool>();
  currUser: IUser = {
    'id': "",
    'permission': ""
  };
  apiService: AlfrescoApiService;
  authService: AuthenticationService;

  constructor(apiService: AlfrescoApiService, authService: AuthenticationService) {
    this.apiService = apiService;
    this.authService = authService;

    this.init();
  }

  init() {
    let userId: string = this.authService.getEcmUsername();    
    this.currUser.id = userId;

//API call
    this.apiService.sitesApi.getSiteMember(SITENAME, userId).subscribe((data:IUser)=> 
  {
    this.user=data;
   this.userFetched.next(true);
  })
 }

  isSiteManager(): boolean {
    console.log(this.currUser.permission, this.currUser);
    if(this.currUser.permission === "SiteManager"){
      return true;
    }else{
      return false;
    }
  }
}

之后,在您的组件中:

export class AppLayoutComponent {

  constructor(permissionService:PermissionService) {
    permissionService.userFetched.subscribe((data)=>{
     permissionService.isSiteManager();
  });
  }
}

这是更好的方法。您需要考虑“主题”或“行为主题”是否更好。

答案 2 :(得分:0)

感谢所有回答的人。我找到了解决方案。我已将isSiteManager()方法更改为一种检查所有四种权限类型的方法。此方法在then()块中执行,并影响每种权限类型的四个变量。我可以从其他组件获得这些变量。 看起来像这样:

 @Injectable()
export class PermissionService {
  isSiteManager: boolean;
  isSiteConsumer: boolean;
  isSiteContributor: boolean;
  isSiteCollaborator: boolean;
  userId : string;

  constructor(private apiService: AlfrescoApiService, private authService: AuthenticationService) {
    this.init();
  }

  init() {
    this.isSiteCollaborator = false;
    this.isSiteConsumer = false;
    this.isSiteContributor = false;
    this.isSiteManager = false;
    this.userId = localStorage.USER_PROFILE;

    //proof permission of user
    this.apiService.sitesApi.getSiteMember(SITENAME, this.userId).then(resp=>{
      if(resp.entry.role === "SiteManager"){
        this.isSiteManager = true;
      }else if(resp.entry.role === "SiteConsumer"){
        this.isSiteConsumer = true;
      }else if(resp.entry.role === "SiteContributor"){
        this.isSiteContributor = true;
      }else{
        this.isSiteCollaborator = true;
      }
    });
  }
}

现在,我可以在其他组件中询问变量了,例如:

export class AppLayoutComponent {

  constructor(private permissionService : PermissionService) {
    if(permissionService.isSiteManager){
      console.log("You are Boss!");
    }
  }
}

答案 3 :(得分:-1)

您应该同步调用服务方法。为此,您必须映射服务响应:

您的组件代码:

constructor() {
...
permissionService.isSiteManager().map(
response => {
    isManager = response;
}
);
}

这样的事情。

要调用地图操作员,请先将其导入:

import 'rxjs/add/operator/map';