Angular 7:如果请求时间过长则采取行动
Angular 7: Taking action if request takes too long
所以我有一个加载图标,它会在应用程序与服务器交互时显示。当请求消失时显示图标,当响应返回时删除图标。相当简单。
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.spinnerService.addPendingLoad();
//We need to add this header to all outbound requests to note this is an XHR request
const authReq = req.clone({
headers: req.headers.set("X-Requested-With", "XMLHttpRequest")
});
return next.handle(authReq).pipe(
tap((event: HttpEvent<any>) => {
if(event instanceof HttpResponse) {
this.spinnerService.removePendingLoad();
}
}));
}
export class SpinnerService {
pendingLoads: number = 0;
constructor(private spinnerService: NgxSpinnerService) {}
addPendingLoad() {
this.pendingLoads++;
this.spinnerService.show();
}
removePendingLoad() {
this.pendingLoads--;
if(this.pendingLoads <= 0) {
this.spinnerService.hide();
}
}
}
所以我想解决的问题是大多数时候请求会立即 return 所以最终发生的是你得到一个非常快的图标 show/hide 它可以是一种不和谐的体验。
我已经尝试将 this.spinnerService.hide();
的超时设置为大约 500 毫秒,这样加载图标将始终在屏幕上显示最短时间。这是一种更令人愉悦的体验,但最终会使加载图标的显示时间比实际显示的时间长,这也会使应用程序变得迟缓 "feel"。
我的目标是能够以某种方式衡量请求已等待多长时间,并且仅在请求花费的时间异常长时才显示加载图标。
例如,大多数请求将在 100 毫秒左右内响应。如果发生某些事情导致响应延迟,则触发加载图标仅在该 100 毫秒标记后显示。因此,如果完整请求耗时 300 毫秒,则加载图标只会在 100 毫秒 -> 300 毫秒后显示。如果请求时间少于 100 毫秒,则无需显示图标。
这样的事情可能吗?我知道边缘情况会发生,就像一个需要 105 毫秒的请求,所以我仍然会遇到那种不和谐的体验,但我认为这是一种权衡,即使不需要,也总是在屏幕上显示加载图标。
您可以在 setTimeout
回调中显示它,而不是立即显示微调器:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let delayExpired = false;
const timeout = setTimeout(() => { // Set spinner timeout
delayExpired = true;
this.spinnerService.addPendingLoad(); // Show spinner after delay
}, 100); // Wait 100 ms to show spinner
...
return next.handle(authReq).pipe(
tap((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
clearTimeout(timeout); // Cancel spinner timeout
if (delayExpired) {
this.spinnerService.removePendingLoad(); // Hide spinner
}
}
}));
}
}
有关演示,请参阅 this stackblitz。
所以我有一个加载图标,它会在应用程序与服务器交互时显示。当请求消失时显示图标,当响应返回时删除图标。相当简单。
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.spinnerService.addPendingLoad();
//We need to add this header to all outbound requests to note this is an XHR request
const authReq = req.clone({
headers: req.headers.set("X-Requested-With", "XMLHttpRequest")
});
return next.handle(authReq).pipe(
tap((event: HttpEvent<any>) => {
if(event instanceof HttpResponse) {
this.spinnerService.removePendingLoad();
}
}));
}
export class SpinnerService {
pendingLoads: number = 0;
constructor(private spinnerService: NgxSpinnerService) {}
addPendingLoad() {
this.pendingLoads++;
this.spinnerService.show();
}
removePendingLoad() {
this.pendingLoads--;
if(this.pendingLoads <= 0) {
this.spinnerService.hide();
}
}
}
所以我想解决的问题是大多数时候请求会立即 return 所以最终发生的是你得到一个非常快的图标 show/hide 它可以是一种不和谐的体验。
我已经尝试将 this.spinnerService.hide();
的超时设置为大约 500 毫秒,这样加载图标将始终在屏幕上显示最短时间。这是一种更令人愉悦的体验,但最终会使加载图标的显示时间比实际显示的时间长,这也会使应用程序变得迟缓 "feel"。
我的目标是能够以某种方式衡量请求已等待多长时间,并且仅在请求花费的时间异常长时才显示加载图标。
例如,大多数请求将在 100 毫秒左右内响应。如果发生某些事情导致响应延迟,则触发加载图标仅在该 100 毫秒标记后显示。因此,如果完整请求耗时 300 毫秒,则加载图标只会在 100 毫秒 -> 300 毫秒后显示。如果请求时间少于 100 毫秒,则无需显示图标。
这样的事情可能吗?我知道边缘情况会发生,就像一个需要 105 毫秒的请求,所以我仍然会遇到那种不和谐的体验,但我认为这是一种权衡,即使不需要,也总是在屏幕上显示加载图标。
您可以在 setTimeout
回调中显示它,而不是立即显示微调器:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let delayExpired = false;
const timeout = setTimeout(() => { // Set spinner timeout
delayExpired = true;
this.spinnerService.addPendingLoad(); // Show spinner after delay
}, 100); // Wait 100 ms to show spinner
...
return next.handle(authReq).pipe(
tap((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
clearTimeout(timeout); // Cancel spinner timeout
if (delayExpired) {
this.spinnerService.removePendingLoad(); // Hide spinner
}
}
}));
}
}
有关演示,请参阅 this stackblitz。