Http请求上的加载指示器 [英] Loading indicator on Http requests

查看:92
本文介绍了Http请求上的加载指示器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题的根源是在http请求上显示一个加载指示器,我想在服务级别上这样做,而不必为每个组件编写代码.我所做的是实现一个http包装器,该包装器基本上可以做到这一点:

The root of my problem is displaying a loading indicator on http requests, and I want to do it at the service level without having to write code for each component. What I did was implement an http wrapper that basically does this:

getMyHttpObservable(...) {
    setLoadingIndicator(true);
    const myHttpObservable = 
        createRequestObservable().finally(()=> {
            console.log('http done');
            setLoadingIndicator(false);
        });
    return myHttpObservable;
}

我有一个可观察的序列,我可以使用Observable.concat如下进行链接:

I have a sequence of observables which I chain using Observable.concat as follows:

const t1 = Observable.timer(5000).finally(()=>console.log('t1 done'));
const t2 = getMyHttpObservable(...);
const agg = Observable.concat(t1,t2);

我正在使用基于事件的取消技术,该技术使用Observable.takeUntil如下:

I am using an event based cancellation technique using Observable.takeUntil as follows:

const ev = new EventEmitter<any>();
const cancellableAgg = agg.takeUntil(ev.asObservable());

现在的问题是,当我在第一个计时器周期内取消可观察的总量时,我没有得到第二个可观察的最终调用-http请求.示例:

Now the problem is when I cancel the aggregate observable during the first timer period I do not get the finally call of the 2nd observable - the http request. Example:

const cancel = Observable.timer(500).finally(()=>ev.emit());
cancellableAgg.subscribe();
cancel.subscribe();

运行上述命令后,我得到以下输出:

When the above runs, I get this output:

t1 done

我也需要获取http done,以便清除加载指示器.我该如何实现?

And I need to get http done as well, so that the loading indicator is cleared. How can I achieve that?

谢谢!

编辑

我没有意识到concat运算符仅在其前辈完成后才订阅可观察对象.我需要的是仅在实际观察到http可观察对象时才激活加载指示器.

I failed to realize that the concat operator only subscribes to observables down the line, when their predecessors have completed. What I need is to activate my loading indicator only when the http observable has actually been subscribed to.

我修改了包装函数,如下所示:

I modified my wrapper function as follows:

getMyHttpObservable(...) {
    const myHttpObservable = createRequestObservable(...);
    const subscriptionAware = new Observable(subscriber => {
        setLoadingIndicator(true);
        myHttpObservable.subscribe(
            nextEv => subscriber.next(nextEv),
            errEv => subscriber.error(errEv),
            () => subscriber.complete())
        .add(()=>setLoadingIndicator(false));
    };
    return subscriptionAware;
}

因此,基本上,我正在创建一个Observable,该Observable透明地包装了另一个Observable,但在实际订阅时还会执行一些其他操作-激活加载指示器.

So basically, I'm creating an Observable which transparently wraps another Observable, but also performs some additional actions when it's actually subscribed to - activate the loading indicator.

但是,由于Observable的构造函数不允许我传递要取消的处理程序,因此现在我已经失去了取消飞行中XHR请求的能力,因此内部订阅将永远不会被取消.

However, now I've lost the ability to cancel XHR requests in flight, since the constructor of Observable doesn't allow me to pass a handler for cancellation, so the inner subscription will never get cancelled.

关于如何实现这一目标的任何想法?

Any ideas as to how to achieve that?

推荐答案

使用内置的defer运算符设法查找解决方案,该运算符等待订阅并返回新鲜的Observable:

Managed to find a solution using the built in defer operator which waits for a subscription and returns a fresh observable:

getMyHttpObservable(...) {
    const myHttpObservable = createRequestObservable(...);
    return Observable.defer(() => {
        setLoadingIndicator(true);
        return myHttpObservable.finally(() => setLoadingIndicator(false));
    });
}

又矮又短.

这篇关于Http请求上的加载指示器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆