Http请求上的加载指示器 [英] Loading indicator on Http requests
问题描述
我的问题的根源是在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屋!