[英]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
声明为async
并await
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.