繁体   English   中英

如何等待一个 function 在 angular 6 执行完之后再执行下面的代码执行?

[英]how to wait for a function to complete its execution in angular 6 before executing the following code execution?

我有两个功能如下:

refreshAccessToken() {
  let rt = this.injector.get(LocalStorageService);
  var tokenData = rt.getAuthorizationData();
  var refreshToken = tokenData.refresh_token;
  var refreshToken = localStorage.getItem('userRefreshToken');
  if (refreshToken !== null) {
    var data = "grant_type=refresh_token&refresh_token=" + refreshToken;
    var basicAuth = btoa("crmClient1:crmSuperSecret");
    var headerData = {
      "Content-Type": "application/x-www-form-urlencoded",
      "Authorization": "Basic " + basicAuth,
      "No-Auth": "True",
      'Access-Control-Allow-Origin': '*'
    };
    var reqHeader = new HttpHeaders(headerData);
    this.http.post(this.tokenUrl, data, {
        headers: reqHeader
      })
      .subscribe((response: any) => {
        this.localStorageService.setAuthorizationData(response);
        console.log("I need to be called first");
      });
  } else {
    return null;
  }
}

getNewAccessToken(): Observable < string > {
  this.refreshAccessToken();
  console.log("I need to be called as a second value");
  var varTokenData = this.localStorageService.getAuthorizationData();
  var newAccessToken = varTokenData.access_token;
  this.newat = newAccessToken;
  return of(this.newat);
}

我在 getNewAccessToken() function 中调用refreshAccessToken() getNewAccessToken() function。这里,除了以下代码外,代码运行良好:

console.log("I need to be called as a second value");
var varTokenData = this.localStorageService.getAuthorizationData();
var newAccessToken = varTokenData.access_token;
this.newat = newAccessToken;
return of(this.newat);

在 function refreshAccessToken()完全执行之前执行。 angular 6中如何让其他代码等待refreshAccessToken() function执行完毕才执行?

我收到的错误如下:

在此处输入图像描述

我调用 getNewAccessToken() function 的 AuthInterceptor 部分如下所示:

//从 refresh_token 生成新令牌

handle401Error(req: HttpRequest<any>, next: HttpHandler) {
    console.log("Error 401 called");
    if (!this.isRefreshingToken) {
        this.isRefreshingToken = true;

        // Reset here so that the following requests wait until the token
        // comes back from the refreshToken call.
        this.tokenSubject.next(null);
        return this.loginService.getNewAccessToken()
        .pipe(
            switchMap((newToken: string) => {
                if (newToken) {
                    this.tokenSubject.next(newToken);
                    //this.isRefreshingToken=false;
                    return next.handle(this.addToken(req, newToken));
                }

                // If we don't get a new token, we are in trouble so logout.
                //this.isRefreshingToken=false;
                return this.logout();
            }),
            catchError(error => {
                // If there is an exception calling 'refreshToken', bad news so logout.
                //this.isRefreshingToken=false;
                //console.log(error);
                return this.logout();
            })
        //)

        ),
        finalize(()=>{
            this.isRefreshingToken=false;
        });   
    } else {
        return this.tokenSubject
            .pipe(
                filter(token => token !=null)
            ),
            take(1),
            switchMap((token: string )=> {
                return next.handle(this.addToken(req,token));
            });
    }
}

您可以从refreshAccessToken方法return Observable

import { of } from 'rxjs';
import { tap } from 'rxjs/operators';

refreshAccessToken(): Observable<any> {
  ...
  if (refreshToken !== null) {
    ...
    return this.http.post(this.tokenUrl, data, {
      headers: reqHeader
    })
    .pipe(tap(response => this.localStorageService.setAuthorizationData(response)));
  } else {
    return of(null);
  }
}

然后从你的getNewAccessToken方法订阅它,如下所示:

getNewAccessToken(): Observable<string> {
  this.refreshAccessToken()
    .subscribe(response => {
      ...
    });
}

或者:

您可以使用ES2017中引入的async / await 因为它们只用于处理promise而不是Observable的函数,所以你必须稍微改变你的函数来返回一个promise而不是Observable

这是如何做:

import { of } from 'rxjs';
import { tap } from 'rxjs/operators';

refreshAccessToken() {
  ...
  if (refreshToken !== null) {
    ...
    return this.http.post(this.tokenUrl, data, {
      headers: reqHeader
    })
    .pipe(tap(response => this.localStorageService.setAuthorizationData(response)))
    .toPromise();
  } else {
    return of(null).toPromise();
  }
}

然后将getNewAccessToken声明为asyncawait refreshAccessToken

async getNewAccessToken() {
  await this.refreshAccessToken();
  ...
}
import { forkJoin } from "rxjs";

async ngOnInit() {
  let data = await this.getDataFromMultipleApis();
  console.log(data);
}
getDataFromMultipleApis(){
   return new Promise((resolve, reject) => {
      forkJoin(
        this.Service.api1(),
        this.Service.api2()
      ).subscribe(docs => {        
        resolve(docs);
      });
    });
}

如果将Observable对象转换为Promise则可以使用TypeScript的async / await模式。 然后,您可以编写看起来更加同步的代码。 然而,值得一提的是,代码本身仍然使用回调和Promise来实际执行,但这是通过语法糖从你身上抽象出来的。

async getNewAccessToken(): Promise<string> {
    // Your refreshAccessToken() needs to always return an Observable now.
    await this.refreshAccessToken().toPromise();
    console.log("I need to be called as a second value");
    var varTokenData = this.localStorageService.getAuthorizationData();
    var newAccessToken = varTokenData.access_token;
    this.newat = newAccessToken;
    return this.newat;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM