我创建了一个服务来处理离子存储的令牌存储。在主页中,我需要检查是否已在使用服务的存储中存在令牌,如果不存在,则将用户重定向到登录页面。下面是主页的代码:
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为null,似乎服务的订阅花费了太多时间,并且该变量保持为null,直到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(['/']);
}
就像上面的点击注销被执行,令牌被删除,问题是,在导航主页令牌仍然存在,因为所有的存储方法是异步的,这就是问题。
1条答案
按热度按时间lkaoscv71#
你没有正确地管理你的国家。你需要假设任何一个任务都可以占用任何时间,你的代码需要处理这个问题。在这里,你需要在加载令牌后将
fetchTokenAndLoadData()
放在某个地方,比如在storage.get
中,或者更好地在订阅(this.tokenService.getTokenAsObservable().subscribe
)中。你还需要一个加载机制,这样在令牌加载之前你就有了一些内容。例如,你可以定义一个像isLoadingToken
这样的变量,并在开始加载令牌之前将其设置为true,并在加载时将其设置为false(无论令牌是否可用),然后根据变量更改HTML的内容。或者使用ion-loading
。我知道你还没有实现checkUserApi
,但这也是另一个异步作业,需要以相同的方式处理,并且是串行加载而不是并行加载。