我正在尝试在RxJS中实现以下行为:
这对用户体验非常有用,因为即使呼叫需要1毫秒,我也想显示至少100毫秒的加载图标。
我没有找到任何方法来实现此问题,包括delay
,throttle
,debounce
或其变体。
this.eventThatFires
.switchMap(data => {
let startTime = Date.now();
return this.callHttpService(data)
.delay(new Date(startTime + 1000));
})
我认为这样的事情有效,但是使用绝对日期似乎与当前时间有所不同,并且没有安排该绝对时间的延迟。
编辑:
似乎没有内置的运算符可以像我描述的那样工作。我刚创建它是因为我将在整个应用程序中大量使用它:
import { Observable } from "rxjs/Observable";
function delayAtLeast<T>(this: Observable<T>, delay: number): Observable<T> {
return Observable.combineLatest(
Observable.timer(delay),
this)
.map(([_, i]) => i);
}
Observable.prototype.delayAtLeast = delayAtLeast;
declare module "rxjs/Observable" {
interface Observable<T> {
delayAtLeast: typeof delayAtLeast;
}
}
答案 0 :(得分:5)
按日期有效delay
与delay
按编号相同,唯一的区别是延迟时间计算为指定日期和当前时间的差异。
您可以使用delayWhen
运算符计算发出值时的延迟:
this.eventThatFires
.switchMap(data => {
let startTime = Date.now();
return this.callHttpService(data)
.delayWhen(() => Rx.Observable.timer(500 + startTime - Date.now()))
})
答案 1 :(得分:2)
您的combineLatest解决方案有什么问题?
您还可以使用zip
:
this.eventThatFires
.switchMap(data => Observable.zip(
this.profileService.updateInfo(profileInfo)),
Observable.timer(500),
x => x));
答案 2 :(得分:1)
我根据Martin的最终解决方案制作了一个自定义rxjs运算符。
import { combineLatest, Observable, OperatorFunction, timer } from "rxjs";
import { map } from "rxjs/operators";
export function delayAtLeast<T>(delay: number): OperatorFunction<T, T> {
return function(source$: Observable<T>): Observable<T> {
return combineLatest([timer(delay), source$]).pipe(map(x => x[1]));
}
}
答案 3 :(得分:0)
基于Bogdan Savluk的答案。延迟功能已解耦:
sbt run
http请求的情况(至少每x秒轮询一次)
let effectiveDelay=(delay)=>{
let effectiveTimer = (now=>delay=>timer(delay+now - Date.now() )) (Date.now())
return delayWhen(()=>effectiveTimer(delay));
}
this.eventThatFires
.switchMap(data => this.callHttpService(data)
.pipe(effectiveDelay(500)))
请参阅:online