es6/operator/throttleTime.js
import { Subscriber } from '../Subscriber';
import { async } from '../scheduler/async';
import { defaultThrottleConfig } from './throttle';
/**
* 从源 Observable 中发出一个值,然后在 `duration` 毫秒内忽略随后发出的源值,
* 然后重复此过程。
*
* <span class="informal">让一个值通过,然后在接下来的 `duration` 毫秒内忽略源值。</span>
*
* <img src="./img/throttleTime.png" width="100%">
*
* 当 `throttle` 的内部定时器禁用时,它会在输出 Observable 上发出源 Observable 的值,
* 并当定时器启用时忽略源值。最开始时,定时器是禁用的。一旦第一个源值达到,它会被转发
* 到输出 Observable ,然后启动定时器。在 `duration` 毫秒(或由可选的 `scheduler`
* 内部确定的时间单位)后,定时器会被禁用,并且下一个源值也是重复此过程。可选择性地
* 接收一个 {@link IScheduler} 用来管理定时器。
*
* @example <caption>以每秒最多点击一次的频率发出点击事件</caption>
* var clicks = Rx.Observable.fromEvent(document, 'click');
* var result = clicks.throttleTime(1000);
* result.subscribe(x => console.log(x));
*
* @see {@link auditTime}
* @see {@link debounceTime}
* @see {@link delay}
* @see {@link sampleTime}
* @see {@link throttle}
*
* @param {number} duration 在发出一个最新的值后,到再发出另外一个值之间的等待时间,
* 以毫秒为单位或以可选的 `scheduler` 内部决定的时间单位来衡量。
* @param {Scheduler} [scheduler=async] 调度器( {@link IScheduler} ),用来
* 管理处理节流的定时器。
* @return {Observable<T>} 该 Observable 执行节流操作,以限制源 Observable 的
* 发送频率。
* @method throttleTime
* @owner Observable
*/
export function throttleTime(duration, scheduler = async, config = defaultThrottleConfig) {
return this.lift(new ThrottleTimeOperator(duration, scheduler, config.leading, config.trailing));
}
class ThrottleTimeOperator {
constructor(duration, scheduler, leading, trailing) {
this.duration = duration;
this.scheduler = scheduler;
this.leading = leading;
this.trailing = trailing;
}
call(subscriber, source) {
return source.subscribe(new ThrottleTimeSubscriber(subscriber, this.duration, this.scheduler, this.leading, this.trailing));
}
}
/**
* We need this JSDoc comment for affecting ESDoc.
* @ignore
* @extends {Ignored}
*/
class ThrottleTimeSubscriber extends Subscriber {
constructor(destination, duration, scheduler, leading, trailing) {
super(destination);
this.duration = duration;
this.scheduler = scheduler;
this.leading = leading;
this.trailing = trailing;
this._hasTrailingValue = false;
this._trailingValue = null;
}
_next(value) {
if (this.throttled) {
if (this.trailing) {
this._trailingValue = value;
this._hasTrailingValue = true;
}
}
else {
this.add(this.throttled = this.scheduler.schedule(dispatchNext, this.duration, { subscriber: this }));
if (this.leading) {
this.destination.next(value);
}
}
}
clearThrottle() {
const throttled = this.throttled;
if (throttled) {
if (this.trailing && this._hasTrailingValue) {
this.destination.next(this._trailingValue);
this._trailingValue = null;
this._hasTrailingValue = false;
}
throttled.unsubscribe();
this.remove(throttled);
this.throttled = null;
}
}
}
function dispatchNext(arg) {
const { subscriber } = arg;
subscriber.clearThrottle();
}
//# sourceMappingURL=throttleTime.js.map