在Angular中使用async / await函数的问题

时间:2019-08-15 14:36:27

标签: javascript angular typescript asynchronous

早上好

即使在阅读了asyncawait的概念和用法之后,我仍然对它们的真实用法有疑问。

基本上在我的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的结果?

3 个答案:

答案 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;

   }