首页 > 解决方案 > 1 秒后显示 ngx 微调器

问题描述

我有一个集中式拦截器,它记录所有 http 请求,并为每个请求加载 ngx-spinner。现在,我希望加载器在 http 请求后延迟 1 秒,如果响应仍在进行中,则显示微调器。如果响应时间少于 1 秒,则没有微调器。

我当前的代码:

@Injectable()
export class SampleInterceptor implements HttpInterceptor {

    count = 0;
    constructor(private spinner: NgxSpinnerService) {
        console.log(spinner);
    }
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
       setTimeout(()=>{
           console.log(this.isRequestServed);
            this.spinner.show();
            this.count++;
       return next.handle(req).pipe(tap(event=>{console.log("change");
        console.log(event)},error=>console.log(error)),
       finalize(()=>{   
            this.count--;
            if(this.count == 0)
             this.spinner.hide();

       }));
    }

}

请让我知道您对我的要求的看法。谢谢。

使用超时更新代码,但由于布尔值,微调器或加载器不显示。

export class SampleInterceptor implements HttpInterceptor {

    count = 0;
    isRequestServed: boolean;
    constructor(private spinner: NgxSpinnerService) {
        console.log(spinner);
    }
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
       setTimeout(()=>{
        if(this.isRequestServed == false) {
            this.spinner.show();
                this.count++;
        }
       },9000);
       return next.handle(req).pipe(tap(event=>{this.isRequestServed = true;
        console.log(event)},error=>console.log(error)),
       finalize(()=>{
           if(this.count > 0 ) {    
            this.count--;
            if(this.count == 0)
             this.spinner.hide();
           }
       }));
    }

}

我正在使用布尔值来确定是否提供了响应。

我通过将事件实例检查到 HttpResponse 来修复它。下面是代码

return next.handle(req).pipe(tap(event=>{
        if(event instanceof HttpResponse) {
            this.isRequestServed = true;
        }},error=>console.log(error)),

拦截返回方法中的这段代码解决了问题。感谢您的意见。

标签: javascriptangularangular8

解决方案


尝试这样的事情

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const time = 900;
    const spinnerLogic = () => {
        if (this.isRequestServed == false) {
            this.spinner.show();
            this.count++;
        }
    };
    const onDataReceive = () => {
        this.isRequestServed = true;
        if (this.count > 0) {
            this.count--;
            if (this.count == 0)
                this.spinner.hide();
        }
    };
    // get a stream with a response
    const res$ = next.handle(req);
    // create a ctream with a function to show spinner and delay it for given time
    const timeout$ = of(spinnerLogic).pipe(delay(time));
    // if response cames before spinner nothing happens ( () => {} will be called instead of a one the to show spinner)
    const spinner$ = merge(res$.pipe(mapTo(() => {})), timeout$).pipe(first());
    // call function - showSpinner or () => {}
    spinner$.subscribe(f => f());
    // i gues you have in HTML | async. If not instead of pipe(finalize) subscribe should be used 
    return res$.pipe(finalize(onDataReceive));
}

工作演示:https ://codesandbox.io/s/rxjs-playground-t34vu?file=/src/index.js


推荐阅读