在执行以下代码之前,如何等待函数在angular 6中完成执行?
我有两个功能,如下所示:在执行以下代码之前,如何等待函数在angular 6中完成执行?,angular,typescript,Angular,Typescript,我有两个功能,如下所示: refreshAccessToken() { let rt = this.injector.get(LocalStorageService); var tokenData = rt.getAuthorizationData(); var refreshToken = tokenData.refresh_token; var refreshToken = localStorage.getItem('userRefreshToken'); if (ref
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);
}
在完全执行函数refreshAccessToken()
之前执行。如何使其他代码等待执行,直到在angular 6中完全执行refreshAccessToken()
函数
我得到的错误如下:
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);
}
AuthInterceptor中调用getNewAccessToken()函数的部分如下所示:
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);
}
//从刷新令牌生成新令牌
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));
});
}
}
handle401Error(请求:HttpRequest,下一步:HttpHandler){
log(“调用错误401”);
如果(!this.isRefreshingToken){
this.isRefreshingToken=true;
//在此处重置,以便以下请求等待令牌
//从refreshToken调用返回。
this.tokenSubject.next(null);
返回这个.loginService.getNewAccessToken()
.烟斗(
开关映射((newToken:string)=>{
如果(纽顿){
this.tokenSubject.next(newToken);
//this.isRefreshingToken=false;
返回next.handle(this.addToken(req,newToken));
}
//如果我们没有得到一个新的令牌,我们有麻烦,所以注销。
//this.isRefreshingToken=false;
返回此参数。注销();
}),
catchError(错误=>{
//如果调用“refreshToken”时出现异常,则会有坏消息,因此请注销。
//this.isRefreshingToken=false;
//console.log(错误);
返回此参数。注销();
})
//)
),
完成(()=>{
this.isRefreshingToken=false;
});
}否则{
返回此.tokenSubject
.烟斗(
过滤器(令牌=>令牌!=null)
),
以(1)为例,
switchMap((令牌:字符串)=>{
返回next.handle(this.addToken(req,token));
});
}
}
您可以从refreshAccessToken
方法返回可观察的:
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);
}
}
或者:
您可以使用ES2017中引入的async
/wait
。由于它们只处理处理promise
s的函数,而不处理Observable
s的函数,因此必须稍微更改函数以返回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
和wait
refreshAccessToken
:
async getNewAccessToken() {
await this.refreshAccessToken();
...
}
如果将可观察的
对象转换为Promise
s,则可以利用TypeScript的模式。然后您可以编写看起来更同步的代码。然而,值得一提的是,代码本身仍然在使用回调并承诺实际执行,但这被语法糖从您那里抽象出来
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;
}
异步getNewAccessToken():承诺{
//您的refreshAccessToken()现在需要始终返回一个可观察值。
等待此消息。refreshAccessToken().toPromise();
log(“我需要作为第二个值调用”);
var varTokenData=this.localStorageService.getAuthorizationData();
var newAccessToken=varTokenData.access\u token;
this.newat=newAccessToken;
返回此.newat;
}
您可以使用async并等待。谢谢您的建议。你能告诉我,我如何实现异步并等待它吗?我将不胜感激。看一看:现在我遇到了这样一个错误:src/app/pagecomponents/utilities/AuthInterceptor.ts(80,14)中的错误:错误TS2339:类型“Promise”上不存在属性“pipe”。我已使用调用getNewAccessToken()的AuthInterceptor部分更新了我的问题这是因为async
方法(在本例中为getNewAccessToken()
)返回的是承诺,而不是可观察的<代码>管道
是一种基于可观察对象的方法。
import { forkJoin } from "rxjs";
async ngOnInit() {
await this.getDataFromMultipleApis().then(data=>{
console.log(data);
});
}
getDataFromMultipleApis(){
return new Promise((res, rej) => {
forkJoin(
this.Service.api1(),
this.Service.api2()
).subscribe(docs => {
res(docs);
});
});
}