我创建了一个服务,该服务的方法可从API检索令牌,该API在内部调用subscribe()。从组件调用此方法,它不返回Observable,而仅返回包含令牌的字符串。
然后,在获得令牌后,应该从组件中调用另一种方法,但是,总是在另一个方法之前调用它。我什至尝试过在组件中使用async / await,但是它没有用。
// api.service.ts
logIn() {
if(!this.token) {
this.http.post(this.apiURL + "/token/", {username: "test", password: "test"}, options).subscribe(response => {
if(response.status == 200) {
this.body = response.body;
this.token = "Token " + this.body.token;
window.sessionStorage.setItem("TOKEN_KEY", this.token);
console.log(this.token);
}
}
return this.token;
}
如您所见,该方法仅返回令牌,所以我在组件中创建一个Promise,一旦解决该问题,就调用getProduct()方法,但在令牌已经存在之前调用它。
// product.component.ts
async getLogin() {
const resp = await this.apiService.logIn();
console.log(resp);
}
getMenu() {
this.apiService.getMenu().subscribe(resp => {
console.log(resp);
});
constructor(private apiService: APIService) {
this.getLogin().then(resp => {
console.log('Called');
// Call before the token has already been created!
this.getMenu();
});
}
问题是您的函数logIn
在异步调用this.token
中设置了this.http.post
的值,因此当您return this.token;
时尚未分配它。您要早点回来。如果要使用Promise方法,则logIn
必须返回Promise
async logIn() {
if(!this.token) {
return this.http.post(this.apiURL + "/token/", {username: "test", password: "test"}, options)
.toPromise()
.then(response => {
if(response.status == 200) {
this.body = response.body;
this.token = "Token " + this.body.token;
window.sessionStorage.setItem("TOKEN_KEY", this.token);
console.log(this.token);
return this.token; // important to return the token here
}
}
}
return this.token;
}
请注意,我已将async
关键字添加到logIn
函数,将subscribe
的toPromise
更改为,与.then
链接并在其中添加了return this.token
。
希望有帮助。
在logIn()
方法中,您应该返回Observable
。
logIn(): Observable<string> {
return this.http
.post(this.apiURL + "/token/", {username: "test", password: "test"}, options)
.pipe(
filter(response => response.status == 200),
map(response => response.body.token),
tap(token => {
window.sessionStorage.setItem("TOKEN_KEY", `Token ${token}`);
})
);
}
然后在构造函数中
constructor(private apiService: APIService) {
this.getLogin().subscribe(token => {
console.log('Called');
// Call before the token has already been created!
this.getMenu();
});
}