要求:
每次发出特定的HTTP请求时,我都需要在UI上显示一个加载微调框。
为了获得良好的视觉效果,我决定将微调器在屏幕上显示至少1秒钟,即使请求的持续时间较短(实际上,此请求的持续时间为0.1s至3-4分钟,所以最好握住微调器持续至少1秒钟)。因此,条件是:
我知道从UI / UX角度来看这种方法值得商bat-但我更愿意将其视为技术挑战。
我尝试过的代码:
正如在SO上的其他实现中发现的那样,我尝试了一种方法combineLatest
-结合使用1的Observable和HTTP请求的Observable。
load() {
this.loading = true; // this will show the spinner
combineLatest(timer(1000), this.service.apiCall())
.pipe(
finalize(()=> {
this.loading = false; // this will hide the spinner
}),
map(x => x[1])
)
.subscribe(x => {
console.log(x);
});
}
如果HTTP请求返回状态200,则此方法效果很好。
问题:
如果HTTP请求返回错误(4 / 5xx),则上面的代码不起作用。HTTP请求结束后,可观察对象立即完成。
我希望微调器具有相同的行为,即使请求首先完成也有错误。
我做了一个简单的Stackblitz,我们可以在其中处理不同的请求:https ://stackblitz.com/edit/spinner-with-min-duration-zcp7hc
谢谢!
从rxjs
文档:
如果至少有一个Observable传递给CombineLatest,并且所有传递的Observable发出了某种东西,则所有组合流完成时,所得的Observable将完成。...另一方面,如果出现任何Observable错误,combinateLatest也将立即错误,所有其他Observable都将被取消订阅。
因此,您必须使用catchError
管道使用其自己的错误捕获例程来处理导致可观察到的错误,以免向combineLatest
操作员抛出错误。这样的事情会起作用。
load() {
this.loading = true; // this will show the spinner
combineLatest(timer(1000),
this.service.apiCall().pipe(
catchError(err)=>{
return of(err); // Return observable wrapped with error.
}))
.pipe(
finalize(()=> {
this.loading = false; // this will hide the spinner
}),
map(x => x[1])
)
.subscribe(x => {
console.log(x);
//Check in the result if there is an error in http
if(x instanceof HttpErrorResponse) {
// do what you want in error scenario.
}
});
}
Stackblitz演示:https ://stackblitz.com/edit/spinner-with-min-duration-ls9dq7
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句