早上好
即使在阅读了async
和await
的概念和用法之后,我仍然对它们的真实用法有疑问。
基本上在我的ngOnInit
中,我调用了一个函数:
ngOnInit() {
this.authenticateUser();
}
功能为:
authenticateUser() {
console.log("----Autenticando Usuário----");
this.token = localStorage.getItem("token");
this.userName = localStorage.getItem("userName");
this.userPhoto = localStorage.getItem("userPhoto");
this.currentUser = this.auth.getSession(this.token);
this.attributions = this.currentUser.sessao.grupos;
this.userEmail = this.currentUser.sessao.email;
this.instalation = this.currentUser.instalacao;
}
问题是currentUser
的值在执行过程中返回为null
,因为它的值是在this.auth.getSession(this.token);
的诺言返回之前设置的。
此Auth
是在名为RestApiService
的服务中构建的
constructor(private auth: RestApiService) { }
我还可以在该服务内使用方法getSession()
,该方法返回JSON
,其中包含来自API
的用户信息
getSession(xtrToken) {
xtrToken = "{\"token\":\"" + xtrToken.toString() + "\"}";
this.http.post(this.apiURL + "/auth", xtrToken)
.subscribe(function (resposta) {
if (resposta != null) {
localStorage.setItem("currentUser", JSON.stringify(resposta));
if (window.location.href.indexOf("?") > -1) {
var url = window.location.href;
var value = url = url.slice(0, url.indexOf('?'));
value = value.replace('@System.Web.Configuration.WebConfigurationManager.AppSettings["BaseURL"]', '');
var newUrl = value;
window.history.pushState({}, null, newUrl);
}
this.currentUser = JSON.parse(localStorage.getItem("currentUser"));
}
});
return this.currentUser;
}
我尝试将getSession
设置为async
,并在其调用中输入如下内容:
async authenticateUser() {
console.log("----Autenticando Usuário----");
this.token = localStorage.getItem("token");
this.userName = localStorage.getItem("userName");
this.userPhoto = localStorage.getItem("userPhoto");
this.currentUser = await this.auth.getSession(this.token);
this.attributions = this.currentUser.sessao.grupos;
this.userEmail = this.currentUser.sessao.email;
this.instalation = this.currentUser.instalacao;
}
但这没什么区别。
因此,有没有办法在我设置API
中的值之前等待this.currentUser
的结果?
答案 0 :(得分:0)
尽管您的getSession
方法尝试执行异步操作,但您尚未将其设置为正确执行。您将在currentUser
块之外返回subscribe
,整个方法无法告诉调用方它是异步的,因此async / await不会有所不同。
对于异步方法,您有几种选择。在Angular中,我们通常使用Observables,因为它们可以实现最大程度的控制。在这种情况下,您可以简单地在http.post
中返回getSession
Observable,然后在authenticateUser
中进行订阅。然后,您可以将以下行放在subscribe
调用内,或者使用pipe
和RxJS运算符执行下一步操作。
您还可以让getSession
返回一个Promise
来解析所需的数据。这样可以使async / await起作用(尽管它不是Angular模式)。
答案 1 :(得分:0)
getSession()必须返回一个promise,以便在这种情况下可以正常工作。
return this.http.post(this.apiURL + "/auth", xtrToken)
.toPromise()
.then(res => res.json())
.catch(err => console.error(err));
或
getSession(){
return new Promise((resolve, reject) => {
...
resolve(data)
})
}
答案 2 :(得分:0)
您可以将映射从rxjs传递到您的返回值并设置为JSON。即使Promise和Observable都是异步操作,也略有不同。当您使用可观察模式时,当您订阅时它会开始监听它,这意味着以后可能会收到多个值(异步)。承诺模式为您提供了一个稍后返回的值,您将在resolve(result)中收听。
login(model: AccessUser) {
return this.http.post(this.endpoint, model).pipe(
map((response: AccessToken) => {
const user = response;
if (user) {
localStorage.setItem('token', user.token);
localStorage.setItem('user', JSON.stringify(user.user));
this.decodedToken = this.jwtHelper.decodeToken(user.token);
this.currentUser = user.user;
}
})
);
}
所以在您的情况下,
getSession(xtrToken) {
xtrToken = "{\"token\":\"" + xtrToken.toString() + "\"}";
this.http.post(this.apiURL + "/auth", xtrToken)
.map((resposta) => {
if (resposta != null) {
localStorage.setItem("currentUser", JSON.stringify(resposta));
if (window.location.href.indexOf("?") > -1) {
var url = window.location.href;
var value = url = url.slice(0, url.indexOf('?'));
value = value.replace('@System.Web.Configuration.WebConfigurationManager.AppSettings["BaseURL"]', '');
var newUrl = value;
window.history.pushState({}, null, newUrl);
}
this.currentUser = JSON.parse(localStorage.getItem("currentUser"));
}
});
return this.currentUser;
}
authenticateUser() {
console.log("----Autenticando Usuário----");
this.token = localStorage.getItem("token");
this.userName = localStorage.getItem("userName");
this.userPhoto = localStorage.getItem("userPhoto");
this.auth.getSession(this.token).subscribe((result) => {
this.currentUser = result;
});
this.attributions = this.currentUser.sessao.grupos;
this.userEmail = this.currentUser.sessao.email;
this.instalation = this.currentUser.instalacao;
}