如何确保可观察对象上的运算符发生在 HTTP 拦截器之后?
How do I ensure operators on an observable occur after a HTTP Interceptor?
在我的 Angular 8 应用程序中,我有一个基本的缓存拦截器:
export class CacheInterceptor implements HttpInterceptor {
constructor(private cache: CacheService) {}
public intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
if (req.method !== 'GET') {
return next.handle(req);
}
const cachedResponse = this.cache.get(req);
if (cachedResponse) {
console.log(cachedResponse);
return of(cachedResponse);
}
return next.handle(req).pipe(
filter(event => event instanceof HttpResponse),
map((response: HttpResponse<any>) => {
this.cache.addToCache(req, response);
return response;
})
);
}
}
我还有一个从外部检索数据的服务API:
public getCases(options: ModuleArguments): Observable<CaseResponse> {
return this.http
.get<CaseResponse>(this.URL_BASE, {
params: options as HttpParams
})
.pipe(map(this.cleanData, this));
}
'cleanData' 方法只是循环接收到的数据并修改一些值以使其更加人性化(例如将 'support_request' 变为 'Support Request')。
似乎正在发生的事情是,在数据 'cleaned' 进入服务后,CacheInterceptor 将响应添加到缓存中。因此,当再次发出相同的请求并从缓存中接收到该请求时,该服务将尝试清理已经清理过的数据。
如何确保 HTTP 响应在被服务修改之前已被拦截并添加到缓存中?
你如何通过将 pipe(map(this.cleanData, this))
操作移动到 Observable 完成并返回你的 CaseResponse
的点来解决这个问题。这可能意味着 HttpInterceptor
已首先应用。
即在你调用 getCases
的地方,你可以尝试这样的事情:
service.getCases(options).subscribe(resolvedData => {
// assuming cleanData(data: CaseResponse) signature
const cleanedData = this.cleanData(resolvedData);
// .. do something with cleanedData
});
此外,从设计的角度来看,您不希望 getCases
做超出预期的事情 - 它是一种执行 HTTP 请求的服务方法,returns它们发送给您的格式。数据的重新格式化最好在该服务功能的消费者处完成——因为消费者很可能需要它 cleaned/reshaped。
在我的 Angular 8 应用程序中,我有一个基本的缓存拦截器:
export class CacheInterceptor implements HttpInterceptor {
constructor(private cache: CacheService) {}
public intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
if (req.method !== 'GET') {
return next.handle(req);
}
const cachedResponse = this.cache.get(req);
if (cachedResponse) {
console.log(cachedResponse);
return of(cachedResponse);
}
return next.handle(req).pipe(
filter(event => event instanceof HttpResponse),
map((response: HttpResponse<any>) => {
this.cache.addToCache(req, response);
return response;
})
);
}
}
我还有一个从外部检索数据的服务API:
public getCases(options: ModuleArguments): Observable<CaseResponse> {
return this.http
.get<CaseResponse>(this.URL_BASE, {
params: options as HttpParams
})
.pipe(map(this.cleanData, this));
}
'cleanData' 方法只是循环接收到的数据并修改一些值以使其更加人性化(例如将 'support_request' 变为 'Support Request')。
似乎正在发生的事情是,在数据 'cleaned' 进入服务后,CacheInterceptor 将响应添加到缓存中。因此,当再次发出相同的请求并从缓存中接收到该请求时,该服务将尝试清理已经清理过的数据。
如何确保 HTTP 响应在被服务修改之前已被拦截并添加到缓存中?
你如何通过将 pipe(map(this.cleanData, this))
操作移动到 Observable 完成并返回你的 CaseResponse
的点来解决这个问题。这可能意味着 HttpInterceptor
已首先应用。
即在你调用 getCases
的地方,你可以尝试这样的事情:
service.getCases(options).subscribe(resolvedData => {
// assuming cleanData(data: CaseResponse) signature
const cleanedData = this.cleanData(resolvedData);
// .. do something with cleanedData
});
此外,从设计的角度来看,您不希望 getCases
做超出预期的事情 - 它是一种执行 HTTP 请求的服务方法,returns它们发送给您的格式。数据的重新格式化最好在该服务功能的消费者处完成——因为消费者很可能需要它 cleaned/reshaped。