debounce.js 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /** PURE_IMPORTS_START .._OuterSubscriber,.._util_subscribeToResult PURE_IMPORTS_END */
  2. var __extends = (this && this.__extends) || function (d, b) {
  3. for (var p in b)
  4. if (b.hasOwnProperty(p))
  5. d[p] = b[p];
  6. function __() { this.constructor = d; }
  7. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  8. };
  9. import { OuterSubscriber } from '../OuterSubscriber';
  10. import { subscribeToResult } from '../util/subscribeToResult';
  11. /**
  12. * Emits a value from the source Observable only after a particular time span
  13. * determined by another Observable has passed without another source emission.
  14. *
  15. * <span class="informal">It's like {@link debounceTime}, but the time span of
  16. * emission silence is determined by a second Observable.</span>
  17. *
  18. * <img src="./img/debounce.png" width="100%">
  19. *
  20. * `debounce` delays values emitted by the source Observable, but drops previous
  21. * pending delayed emissions if a new value arrives on the source Observable.
  22. * This operator keeps track of the most recent value from the source
  23. * Observable, and spawns a duration Observable by calling the
  24. * `durationSelector` function. The value is emitted only when the duration
  25. * Observable emits a value or completes, and if no other value was emitted on
  26. * the source Observable since the duration Observable was spawned. If a new
  27. * value appears before the duration Observable emits, the previous value will
  28. * be dropped and will not be emitted on the output Observable.
  29. *
  30. * Like {@link debounceTime}, this is a rate-limiting operator, and also a
  31. * delay-like operator since output emissions do not necessarily occur at the
  32. * same time as they did on the source Observable.
  33. *
  34. * @example <caption>Emit the most recent click after a burst of clicks</caption>
  35. * var clicks = Rx.Observable.fromEvent(document, 'click');
  36. * var result = clicks.debounce(() => Rx.Observable.interval(1000));
  37. * result.subscribe(x => console.log(x));
  38. *
  39. * @see {@link audit}
  40. * @see {@link debounceTime}
  41. * @see {@link delayWhen}
  42. * @see {@link throttle}
  43. *
  44. * @param {function(value: T): SubscribableOrPromise} durationSelector A function
  45. * that receives a value from the source Observable, for computing the timeout
  46. * duration for each source value, returned as an Observable or a Promise.
  47. * @return {Observable} An Observable that delays the emissions of the source
  48. * Observable by the specified duration Observable returned by
  49. * `durationSelector`, and may drop some values if they occur too frequently.
  50. * @method debounce
  51. * @owner Observable
  52. */
  53. export function debounce(durationSelector) {
  54. return function (source) { return source.lift(new DebounceOperator(durationSelector)); };
  55. }
  56. var DebounceOperator = /*@__PURE__*/ (/*@__PURE__*/ function () {
  57. function DebounceOperator(durationSelector) {
  58. this.durationSelector = durationSelector;
  59. }
  60. DebounceOperator.prototype.call = function (subscriber, source) {
  61. return source.subscribe(new DebounceSubscriber(subscriber, this.durationSelector));
  62. };
  63. return DebounceOperator;
  64. }());
  65. /**
  66. * We need this JSDoc comment for affecting ESDoc.
  67. * @ignore
  68. * @extends {Ignored}
  69. */
  70. var DebounceSubscriber = /*@__PURE__*/ (/*@__PURE__*/ function (_super) {
  71. __extends(DebounceSubscriber, _super);
  72. function DebounceSubscriber(destination, durationSelector) {
  73. _super.call(this, destination);
  74. this.durationSelector = durationSelector;
  75. this.hasValue = false;
  76. this.durationSubscription = null;
  77. }
  78. DebounceSubscriber.prototype._next = function (value) {
  79. try {
  80. var result = this.durationSelector.call(this, value);
  81. if (result) {
  82. this._tryNext(value, result);
  83. }
  84. }
  85. catch (err) {
  86. this.destination.error(err);
  87. }
  88. };
  89. DebounceSubscriber.prototype._complete = function () {
  90. this.emitValue();
  91. this.destination.complete();
  92. };
  93. DebounceSubscriber.prototype._tryNext = function (value, duration) {
  94. var subscription = this.durationSubscription;
  95. this.value = value;
  96. this.hasValue = true;
  97. if (subscription) {
  98. subscription.unsubscribe();
  99. this.remove(subscription);
  100. }
  101. subscription = subscribeToResult(this, duration);
  102. if (!subscription.closed) {
  103. this.add(this.durationSubscription = subscription);
  104. }
  105. };
  106. DebounceSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) {
  107. this.emitValue();
  108. };
  109. DebounceSubscriber.prototype.notifyComplete = function () {
  110. this.emitValue();
  111. };
  112. DebounceSubscriber.prototype.emitValue = function () {
  113. if (this.hasValue) {
  114. var value = this.value;
  115. var subscription = this.durationSubscription;
  116. if (subscription) {
  117. this.durationSubscription = null;
  118. subscription.unsubscribe();
  119. this.remove(subscription);
  120. }
  121. this.value = null;
  122. this.hasValue = false;
  123. _super.prototype._next.call(this, value);
  124. }
  125. };
  126. return DebounceSubscriber;
  127. }(OuterSubscriber));
  128. //# sourceMappingURL=debounce.js.map