debounce.js 5.1KB

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