我创建了一个服务来处理离子存储的令牌存储。在主页中,我需要使用该服务检查存储中是否已存在令牌,如果不存在,则将用户重定向到登录页面。这是主页的代码:
ngOnInit(){
this.storage.create() // da fare solo una volta all'avvio dell'app
this.storage.get('jwtToken').then(token => {
this.tokenService.saveToken(token);
});
this.tokenService.getTokenAsObservable().subscribe(
token => {
this.token = token;
let tokan = token;
}
);
if(!this.storage.get('jwtToken')){
this.router.navigate(['/login']);
} else if (!this.checkUserApi()){
this.router.navigate(['/login']);
}
else {
this.storage.get('jwtToken').then(token => {
this.tokenService.saveToken(token);
});
this.initFirebase()
}
}
checkUserApi(){
return true
}
ionViewWillEnter(){
this.fetchTokenAndLoadData();
}
async fetchTokenAndLoadData() {
try {
this.token = await this.storage.get('token');
if (this.token) {
await this.loadData();
} else {
console.log('Token not found');
}
} catch (error) {
console.error('Error fetching token:', error);
}
}
问题是,当我运行应用程序时,变量 this.token 为空,似乎服务的订阅花费了太多时间,并且该变量保持为空,直到 ionwillEnter
编辑: 我使用服务来处理存储:
export class TokenService {
private tokenSubject: BehaviorSubject<string> = new BehaviorSubject<string>('');
constructor(private storage: Storage) {
this.init();
}
async init() {
const token = await this.storage.get('jwtToken');
this.tokenSubject.next(token);
}
async saveToken(token: string): Promise<void> {
await this.storage.set('jwtToken', token);
this.tokenSubject.next(token);
}
async removeToken(): Promise<void> {
await this.storage.remove('jwtToken');
this.tokenSubject.next('');
}
getTokenAsObservable(): Observable<string> {
return this.tokenSubject.asObservable();
}
}
并在应用程序的其他部分使用这些方法来创建、删除令牌。 示例:
logout(){
this.tokenService.removeToken();
this.router.navigate(['/']);
}
像上面一样,单击执行注销并删除令牌,问题是在导航主页时令牌仍然存在,因为所有存储方法都是异步的,这就是问题。
您没有正确管理您的状态。您需要假设任何异步任务都可能需要任何时间,您的代码需要处理该问题。在这里,您需要在加载令牌后将
fetchTokenAndLoadData()
放在某个位置,例如在 storage.get
中或更好地放在订阅中 (this.tokenService.getTokenAsObservable().subscribe
)。您还需要一个加载机制,以便在加载令牌之前您会拥有一些内容。例如,您可以定义一个像 isLoadingToken
这样的变量,并在开始加载令牌之前将其设置为 true,并在加载时将其设置为 false(无论令牌是否可用),然后更改基于 html 的内容在变量上。或者可以使用 ion-loading
。
我意识到您还没有实现 checkUserApi
,但这也是另一个异步作业,需要以相同的方式处理,并且与加载串联而不是并行。