我创建了一个拦截器,目的是让它向每个请求附加一个查询字符串元素。要知道将哪个值附加到必须连接到服务的查询字符串,请从该服务返回一个观察值,然后切换映射以返回拦截器所期望的HTTPRequest。
@Injectable()
export class PermCheckInterceptor implements HttpInterceptor {
constructor(public userService: UserService) {}
intercept(req: HttpRequest < any > , handler: HttpHandler): Observable < httpEvent < any >> {
return this userService.currentUser.pipe(
switchMap(curUser => {
return handler.handle(reg.clone {
setParams: {
"perm": curUser.hasPerms ? 'true' : 'false'
}
}));
}
}目前这段代码没有抛出错误,但在运行站点时它只是挂起了,我认为这是因为拦截器永远不会解决问题。这行代码:
userService.currentUser.pipe上面的代码连接到一个服务并返回一个从主题创建的可观察对象(使用.asObservable() )。
我的猜测是,在拦截器首次运行时,可观察对象尚未触发或可用,因此它只是挂起。不过,这只是一种猜测。
上面的代码看起来有什么问题吗?在继续拦截器之前,有没有办法检查可观察对象是否有值,或者有没有更好的方法来这样做?
发布于 2021-02-04 18:55:31
因此,第一步是进行调试,以确保您知道问题所在。正如您所说的,在拦截器订阅之后,userService.currentUser似乎确实不会发送值。
在此语句switchMap(curUser => {之后使用您首选的调试方法来检查它是否实际发出以及值是什么。还要检查intercept()是否在第一时间被调用(我假设您已经进行了配置,但只是以防万一)。
如果我猜测,userService正在使用Subject,而您正在发出一个值,但它只发出一次,当拦截器订阅该值时,该值已经发出,因此流中没有其他东西。从代码的外观来看,我可能会推荐使用ReplaySubject,每当添加新的订阅者时,它都会重放许多以前的值。(更多信息请阅读:https://www.learnrxjs.io/learn-rxjs/subjects/replaysubject)
因此,当您在用户服务中实例化您的主题时,您可以这样做:
this.userSubject = new ReplaySubject(1);传递给ReplaySubject构造函数的1指示当新订阅者订阅时将重放多少值。因此,当拦截器订阅时,它将立即获得发出的最后一个值。
https://stackoverflow.com/questions/66043483
复制相似问题