Repositorio del curso CCOM4030 el semestre B91 del proyecto Artesanías con el Instituto de Cultura

audit.ts 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import { Operator } from '../Operator';
  2. import { Subscriber } from '../Subscriber';
  3. import { Observable } from '../Observable';
  4. import { Subscription } from '../Subscription';
  5. import { MonoTypeOperatorFunction, SubscribableOrPromise, TeardownLogic } from '../types';
  6. import { SimpleOuterSubscriber, innerSubscribe, SimpleInnerSubscriber } from '../innerSubscribe';
  7. /**
  8. * Ignores source values for a duration determined by another Observable, then
  9. * emits the most recent value from the source Observable, then repeats this
  10. * process.
  11. *
  12. * <span class="informal">It's like {@link auditTime}, but the silencing
  13. * duration is determined by a second Observable.</span>
  14. *
  15. * ![](audit.png)
  16. *
  17. * `audit` is similar to `throttle`, but emits the last value from the silenced
  18. * time window, instead of the first value. `audit` emits the most recent value
  19. * from the source Observable on the output Observable as soon as its internal
  20. * timer becomes disabled, and ignores source values while the timer is enabled.
  21. * Initially, the timer is disabled. As soon as the first source value arrives,
  22. * the timer is enabled by calling the `durationSelector` function with the
  23. * source value, which returns the "duration" Observable. When the duration
  24. * Observable emits a value or completes, the timer is disabled, then the most
  25. * recent source value is emitted on the output Observable, and this process
  26. * repeats for the next source value.
  27. *
  28. * ## Example
  29. *
  30. * Emit clicks at a rate of at most one click per second
  31. * ```ts
  32. * import { fromEvent, interval } from 'rxjs';
  33. * import { audit } from 'rxjs/operators'
  34. *
  35. * const clicks = fromEvent(document, 'click');
  36. * const result = clicks.pipe(audit(ev => interval(1000)));
  37. * result.subscribe(x => console.log(x));
  38. * ```
  39. * @see {@link auditTime}
  40. * @see {@link debounce}
  41. * @see {@link delayWhen}
  42. * @see {@link sample}
  43. * @see {@link throttle}
  44. *
  45. * @param {function(value: T): SubscribableOrPromise} durationSelector A function
  46. * that receives a value from the source Observable, for computing the silencing
  47. * duration, returned as an Observable or a Promise.
  48. * @return {Observable<T>} An Observable that performs rate-limiting of
  49. * emissions from the source Observable.
  50. * @method audit
  51. * @owner Observable
  52. */
  53. export function audit<T>(durationSelector: (value: T) => SubscribableOrPromise<any>): MonoTypeOperatorFunction<T> {
  54. return function auditOperatorFunction(source: Observable<T>) {
  55. return source.lift(new AuditOperator(durationSelector));
  56. };
  57. }
  58. class AuditOperator<T> implements Operator<T, T> {
  59. constructor(private durationSelector: (value: T) => SubscribableOrPromise<any>) {
  60. }
  61. call(subscriber: Subscriber<T>, source: any): TeardownLogic {
  62. return source.subscribe(new AuditSubscriber<T, T>(subscriber, this.durationSelector));
  63. }
  64. }
  65. /**
  66. * We need this JSDoc comment for affecting ESDoc.
  67. * @ignore
  68. * @extends {Ignored}
  69. */
  70. class AuditSubscriber<T, R> extends SimpleOuterSubscriber<T, R> {
  71. private value?: T;
  72. private hasValue: boolean = false;
  73. private throttled?: Subscription;
  74. constructor(destination: Subscriber<T>,
  75. private durationSelector: (value: T) => SubscribableOrPromise<any>) {
  76. super(destination);
  77. }
  78. protected _next(value: T): void {
  79. this.value = value;
  80. this.hasValue = true;
  81. if (!this.throttled) {
  82. let duration;
  83. try {
  84. const { durationSelector } = this;
  85. duration = durationSelector(value);
  86. } catch (err) {
  87. return this.destination.error!(err);
  88. }
  89. const innerSubscription = innerSubscribe(duration, new SimpleInnerSubscriber(this));
  90. if (!innerSubscription || innerSubscription.closed) {
  91. this.clearThrottle();
  92. } else {
  93. this.add(this.throttled = innerSubscription);
  94. }
  95. }
  96. }
  97. clearThrottle() {
  98. const { value, hasValue, throttled } = this;
  99. if (throttled) {
  100. this.remove(throttled);
  101. this.throttled = undefined;
  102. throttled.unsubscribe();
  103. }
  104. if (hasValue) {
  105. this.value = undefined;
  106. this.hasValue = false;
  107. this.destination.next!(value);
  108. }
  109. }
  110. notifyNext(): void {
  111. this.clearThrottle();
  112. }
  113. notifyComplete(): void {
  114. this.clearThrottle();
  115. }
  116. }