简体   繁体   English

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

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

I have a two functions as below:我有两个功能如下:

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);
}

I am calling refreshAccessToken() function inside getNewAccessToken() function. Here, the code is doing fine except that the codes:我在 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);

are executed before the complete execution of function refreshAccessToken() .在 function refreshAccessToken()完全执行之前执行。 How do I make other codes wait for execution until the refreshAccessToken() function is completely executed in angular 6? angular 6中如何让其他代码等待refreshAccessToken() function执行完毕才执行?

The error I am getting is as below:我收到的错误如下:

在此处输入图像描述

The section of AuthInterceptor from where I a calling getNewAccessToken() function is as below:我调用 getNewAccessToken() function 的 AuthInterceptor 部分如下所示:

//generating new token from refresh_token //从 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));
            });
    }
}

You can return an Observable from your refreshAccessToken method: 您可以从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);
  }
}

And then subscribe to it from your getNewAccessToken method like this: 然后从你的getNewAccessToken方法订阅它,如下所示:

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

Alternatively: 或者:

You could use async / await which were introduced in ES2017. 您可以使用ES2017中引入的async / await Since they work only with functions dealing with promise s and not Observable s, you will have to change your functions a bit to return a promise instead of Observable . 因为它们只用于处理promise而不是Observable的函数,所以你必须稍微改变你的函数来返回一个promise而不是Observable

Here's how: 这是如何做:

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();
  }
}

And then declare getNewAccessToken as async and await refreshAccessToken : 然后将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);
      });
    });
}

You could leverage TypeScript's async/await pattern if you convert the Observable objects to Promise s. 如果将Observable对象转换为Promise则可以使用TypeScript的async / await模式。 Then you can write code that looks more synchronous. 然后,您可以编写看起来更加同步的代码。 It's worth calling out, however, that the code itself is still using callbacks and Promises to actually execute, but that's abstracted away from you by the syntactic sugar. 然而,值得一提的是,代码本身仍然使用回调和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