【发布时间】:2020-05-28 13:02:17
【问题描述】:
设置:
我有一个函数 isAuthorized(),在一个单例 AuthSessionSingleton 中,它依赖于异步函数的结果。
异步函数是一个api调用,在构造函数中调用,它期望返回一个对象。 isAuthorized() 依赖于那个对象。
问题:
在后端调用解析之前,某些组件会立即调用函数isAuthorized()。
我希望能够在 isAuthorized() 函数内等待,直到后端调用解决并且 object 不再为空。
简单代码:
//auth.singleton.ts
@Injectable({providedIn: 'root'})
export class AuthSessionSingleton {
userInfo: UserInfo = null;
constructor(private service: MyService) {
this.loadUserInfo();
}
loadUserInfo() {
this.service.makeBackendCall().subscribe({
next: (obj: UserInfo) => {
this.userInfo = obj;
}
});
}
isAuthorized() {
if(this.userInfo == null) {
// do something to wait asynchronously
}
// Very simple example
if(this.userInfo.Role == 'Admin') {
return true;
}
return false;
}
}
//some.component.ts
export class SomeComponent {
authorized: boolean = false;
constructor(private auth: AuthSessionSingleton) {
this.checkAuthorization();
}
async checkAuthorization() {
this.authorized = await this.auth.isAuthorized();
}
}
在上面的简化程序中,调用 isAuthorized() 的 SomeComponent 可能会在 userInfo 仍然为空时检查它。我需要等待它不为空。
可能的解决方案:
到目前为止,我已经确定了许多解决方案。我正在寻找最正确的解决方案,希望是我从未想过的解决方案。
1。收听订阅
在isAuthorized()、if(this.userInfo==null) 订阅与loadUserInfo() 相同的订阅并等待它。
2。等到发出信号
我可以在 AuthSessionSingleton 中创建一个 Subject 并从 SomeComponent 订阅,等到我收到信号,然后调用 IsAuthorized()。
这似乎特别迂回。
3。等一下
有很多方法可以让我旋转我的齿轮,直到我需要的对象不再为空。
while(this.userInfo == null) {
// do something
}
请求:
我想要一种在isAuthorized() 中异步等待直到this.userInfo != null 的方法。可以对isAuthorized() 进行任意数量的调用(来自不同的组件),并且所有调用都应该等到该值被解析。
有什么想法吗?
编辑
我现在意识到一个更准确的用例改变了可能的解决方案。通过接受一组值进行循环,它变得更加复杂。
isAuthorized(roles: string[]) {
let(i = 0; i < roles.length; i++) {
let role = roles[i];
if(this.userInfo.Role == role) {
return true;
}
return false;
}
}
【问题讨论】:
-
我会使用解决方案 2,但您可以使
isAuthorized()函数异步并在调用完成后返回状态。在解决方案 1 中,如果您订阅相同的端点,您将触发额外的不需要的 HTTP 请求。如果后端不回复,解决方案 3 可能会导致无限循环。 -
如果你的应用在你的 api 调用完成之前不初始化会好吗?
标签: angular asynchronous async-await rxjs singleton