angular - RXJS/Angular 替换 Observable
问题描述
在角度拦截器中,我想检查是否存在身份验证令牌。如果不是,则应刷新并重新发送请求。
return next.handle(authReq).pipe(map((result: any) => {
if (result.body && result.body.error) {
if (result.body.error === 'ERR_TOKEN_EXPIRED' || result.body.error === 'ERR_TOKENS_DO_NOT_MATCH') {
console.log('Token is expired or invalid, refreshing.', result.body.error);
return this.userService.refreshLoginToken().subscribe(success => {
if (success) {
return this.intercept(req, next);
}
});
}
}
return result;
}));
问题是我不知道如何将 next.handle() 返回的原始 Observable 替换为新的。之前的 return 语句this.userService.refreshLoginToken().subscribe()
返回一个 Subscription 对象。如果我只是通过管道传输它的结果refreshLoginToken()
将不起作用,因为 refreshLoginToken 发送一个 httprequest,该请求仅在有订阅时执行。
将问题简化为一行:如何将第 1 行中由 next.handle() 返回的 Observable 替换为由返回的 Observable this.intercept(req, next)
?
谢谢!
解决方案
我认为你应该以不同的方式来做这件事。
请检查下面的示例和最新的switchMap
:
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {Injectable} from '@angular/core';
import {StoreState} from '@core/store';
import {select, Store} from '@ngrx/store';
import {getAuthToken} from '@v2/core/store/auth/auth.reducer';
import {iif, Observable, of} from 'rxjs';
import {switchMap, take} from 'rxjs/operators';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(protected readonly store: Store<StoreState>) {}
public intercept(request: HttpRequest<void>, next: HttpHandler): Observable<HttpEvent<void>> {
return this.store.pipe(
select(getAuthToken),
take(1),
switchMap(token =>
iif(
() => !token,
of(request),
of(
request.clone({
setHeaders: {
Authorization: `Bearer ${token?.accessToken}`,
},
}),
),
),
),
switchMap(clonedRequest => next.handle(clonedRequest)),
);
}
}
推荐阅读
- facebook-graph-api - 当在 facebook 中发布带有特定字符串的帖子时,如何从 facebook 获取 webhook 通知
- reactjs - 尽管创建了文件对象,但 Multer req.file 始终未定义
- pandas - 比较一个数据框列在不同数据框的另外两列之间
- javascript - 物化搜索,自动完成。如何根据所选选项更改站点?
- lua - GetPlayers 不能在服务器端脚本上工作
- python-3.x - 如何在 PyMongo 中使用 OR 语句和变量赋值?
- java - 为什么代码的执行会跳过“食物在桌子上”的第一条语句?
- reactjs - React-Admin:在列表中显示之前映射资源数据
- html - Bootstrap 汉堡菜单改变位置
- json - 使用动态字段 json 快速发送请求