Rad*_*ari 7 observable rxjs typescript angular
我正在尝试在我的Angular2应用程序上实现刷新令牌.我采取乐观的方法,而不是在发出请求之前检查访问令牌是否过期,我正在发出请求,如果它返回401代码,我将通过请求新的令牌并将其保存到本地存储来刷新访问令牌.
这是我的代码片段:
getWithParams<T>(serviceUrl: string, params: URLSearchParams): Observable<T> {
return super.getWithParams<T>(serviceUrl, params)
.retryWhen((error) => {
return error
.filter((e) => e.status === 401)
.scan((acc, value) => {
return acc + 1;
}, 0)
.takeWhile(acc => acc < 3)
.flatMap(() => this.tokenRefreshService.refreshToken())
.delay(1000);
});
}
Run Code Online (Sandbox Code Playgroud)
值得一提的是,super.getWithParams通过从本地存储中检索访问令牌来设置访问令牌.
方法调用tokenRefreshService.refreshToken()获取新的访问令牌并将其保存到本地存储.
我面临的问题是,当重试请求时,它正在使用旧的访问令牌,也就是说,它不会再调用super.getWithParams来重建请求.它只是重试现有的观察.
有没有办法再次建立请求?或者查看失败的observable的请求标头?
实际上retryWhen()
重新订阅其来源,以便您可以利用它.这个例子应该模拟你的情况:
let token = 'token';
let counter = 0;
const source$ = Rx.Observable.defer(() => {
console.log('Observable.defer(), token: ' + token);
return Rx.Observable.of(token);
})
.map(token => {
if (counter++ < 3) {
throw new Error('invalid token');
}
return token;
})
.retryWhen((error) => {
return error
.filter(() => true) // or whatever...
.do(() => token = token + 'bla'); // update the token
})
.map(token => { // create the request
return "I'm a request with token: " + token;
});
source$.subscribe(
res => console.log(res),
err => console.log('error: ' + err),
() => console.log('complete')
);
Run Code Online (Sandbox Code Playgroud)
观看现场演示:https://jsbin.com/produqi/5/edit?js,console
这三次抛出了无效令牌的错误,并且每次都会更新它.
请注意,在每个错误上我都在创建一个新的源Observable Observable.defer
.
此示例打印到控制台:
Observable.defer(), token: token
Observable.defer(), token: tokenbla
Observable.defer(), token: tokenblabla
Observable.defer(), token: tokenblablabla
I'm a request with token: tokenblablabla
complete
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1332 次 |
最近记录: |