Angular拦截器挂起



我创建了一个拦截器,目的是将查询字符串元素附加到每个请求。为了知道要将哪个值附加到查询字符串上,我必须连接到一个服务,从该服务返回一个可观察对象,然后切换映射以返回拦截器期望的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

上面代码中的连接到一个服务,并返回一个从Subject创建的可观察对象(使用. asobservable())。

我的猜测是,在拦截器第一次运行时,可观察对象还没有被触发或可用,所以它只是挂起。这只是个猜测。

上面的代码有什么问题吗?是否有一种方法来检查可观察对象有一个值之前继续与拦截器或有一个更好的方式来做这个?

所以第一步是调试,以确保您知道问题在哪里。正如你所说,在拦截器订阅后,userService.currentUser似乎没有发出值。

在此语句switchMap(curUser => {之后使用您首选的调试方法来检查它是否实际发出以及值是什么。还要检查intercept()是否在第一个地方被调用(我假设你已经配置了,但以防万一)。

如果我习惯猜测,userService正在使用Subject,并且您正在发出一个值,但它只发出一次,然后当拦截器订阅该值时,该值已经发出,因此没有其他东西从流中流出。根据代码的外观,我可能会建议使用ReplaySubject,它在添加新订阅者时重播许多以前的值。(阅读更多:https://www.learnrxjs.io/learn-rxjs/subjects/replaysubject)

当你在用户服务中实例化你的主题时你可以这样做:

this.userSubject = new ReplaySubject(1);

传递给ReplaySubject构造函数的1规定了在新订阅者订阅时将重播多少个值。因此,当拦截器订阅时,它将立即获得最后一个发出的值。

最新更新