【问题标题】:Angular: How to show something on slow HTTP responseAngular:如何在缓慢的 HTTP 响应中显示某些内容
【发布时间】:2020-04-04 12:06:41
【问题描述】:

在我的 Angular 应用程序中,我想在服务器响应缓慢时显示具有 取消重新加载 按钮的文本/模式。

如果用户点击取消,当前的http请求将被取消。如果用户点击重新加载,当前的 http 请求将被重试。如果文本/模态已经显示并且 HTTP 请求已经响应/完成,那么文本/模态应该消失。

我有一个使用 HTTP 拦截器、RxJS 和全局服务的想法,但实现起来并不容易。

有没有人有想法,如何以正确的方式做到这一点?

编辑:哦,我想让它成为一个通用模块,这样每个 http 请求都可以取消或重新加载。所以每个页面都可以有这个功能

【问题讨论】:

  • 你能在你到目前为止所尝试的基础上创建一个堆栈闪电战吗?
  • 对不起,不。仍在尝试一些想法。我目前所做的是使用具有 onCancel 和 onReload observables 的服务。并从 Interceptor 尝试订阅这些 observables。不过我需要别人的意见

标签: angular rxjs rxjs6 angular-http-interceptors


【解决方案1】:

使用takeUntil 取消/中止所有挂起的 HTTP 请求

您可以使用takeUntil 来停止正在进行的请求,因为来自HttpClient 的请求会返回一个可观察对象,您可以很容易地做到这一点:

TS

userStop$: Subject<boolean> = new Subject<boolean>();

makeRequest() {
    this.userStop$.next(false);
    // Service Call
    this.apiService.makeRequest().pipe(
        takeUntil(this.userStop$)
    ).subscribe(...);
}

handleUserStop() {
    this.userStop$.next(true);
}

例如,当您通过单击按钮将userStop$ 更改为true 时,它​​将停止。要重试,您只需调用服务方法并将userStop$ 设置为false;

如果你想在请求失败后重试,可以使用retry(x)

this.apiService.makeRequest().pipe(
    //retry 2 times on error
    retry(2)
).subscribe(...);

您也可以查看:How to cancel/unsubscribe all pending HTTP requests angular 4+

欲了解更多信息:https://www.learnrxjs.io/operators/filtering/takeuntil.html

【讨论】:

  • 我已经有类似的代码了。但是有没有什么办法,对于每个 http 请求,计算获得响应所花费的时间,然后向用户显示取消或重做请求可观察流的选项。
  • 取消一个请求显然会完成 observable。对于那些您可以使用Subject 不断推送新请求的人,但是由于抛出错误,获得404 或超时将始终完成observable。您需要设置一个备用值以防出错。
  • 除此之外,您的描述看起来有点不清楚您真正想要什么。使用 takeUntil 应该可以实现您想要的:用户可以重试请求并取消它。
【解决方案2】:

你需要使用reportProgress的HttpRequest。这里有一个解释如何做到这一点https://stackoverflow.com/a/47034525/9590251。但请记住,它会侦听每个更改检测,从而大大降低应用程序的性能。建议用于繁重的请求(即文件上传)

【讨论】:

    【解决方案3】:
    1. 创建可取消订阅

    这很容易。像这样在组件中创建一个属性:

    dataSubscription: Subscription

    在触发请求的事件处理程序中,像这样创建它:

    dataSubscription = someService.someRESTApiCalls.subscribe(....)

    任何时候,你想停止这个,你可以打电话

    this.dataSubscription.unsubscribe()

    我还建议使用ngOnDestroy 挂钩,并在需要时取消订阅:

    ngOnDestroy(){
    
       if(this.dataSubscription) this.dataSubscription.unsubscribe();
    }
    

    取消通话。

    1. 模态

    对于模态,我推荐Angular Material Modal

    1. 逻辑

    在组件isResponseArrived: boolean 中创建一个类属性。用户发起请求后,在事件处理程序中将其设置为 false,并显示任何您想要 shuw 的内容,并带有 ngIf="!isResponseArrived"˛ 响应到达后,在订阅响应处理程序中将 flags 值修改为 true(两者都具有值,或出错)。

    +1:检测订阅是否耗时过长

    使用 httpClient 超时 (source):

    this.httpClient.get(url, { headers: headers })
            .timeout(30000)
            .subscribe(
                (response) => {
                    ...
                },
                error => {
                    ...
                }
                    ...
                );
    

    【讨论】:

    • 如何检测订阅时间是否超过 x 秒?在我知道响应需要很长时间后,我可以取消或重新加载它。
    • 不会超时自动出错/完成流吗?有没有办法不完成流?让客户端仍然在等待响应,但同时,用户会收到当前 http 耗时较长的通知,可以取消或重做。
    【解决方案4】:

    假设您的请求需要 20 秒才能完成响应,那么您可以在 20 秒内取消它

    通过简单的UnSubscription那个请求

    import { Component, OnInit, OnDestroy } from '@angular/core';
        import { Subscription } from 'rxjs/Rx';
    
        export class Component implements OnInit, OnDestroy {
            private subscription: Subscription;
            ngOnInit() {
                this.subscription = this.route.params.subscribe();
            }
            ngOnDestroy() {
                this.subscription.unsubscribe();
            }
    
    
    
         cancel() {
                this.subscription.unsubscribe();
            }
    
        retry() {
                this.subscription.subscribe();
            }
    
    
    
        }
    

    html 当您发出任何 http 请求时,您可以在任何时间或任何地方弹出一个按钮,以便能够取消它

         <div> {{ subscription | async }}</div>
    .
    .
    .Enter your other logic
    .
    
    
        <button (click)=="cancel()" > Cancel Request</button>
        <button (click)=="retry()" > Cancel retry</button>
    

    【讨论】:

    • 我不想只是取消订阅/取消。我希望让用户选择在一段时间后取消或重试
    • @same 你可以创建重试方法亲爱的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-20
    • 1970-01-01
    • 2017-06-04
    • 1970-01-01
    • 2018-04-12
    • 1970-01-01
    相关资源
    最近更新 更多