123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /** PURE_IMPORTS_START .._Subscriber,.._Observable,.._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 { Subscriber } from '../Subscriber';
  10. import { Observable } from '../Observable';
  11. import { OuterSubscriber } from '../OuterSubscriber';
  12. import { subscribeToResult } from '../util/subscribeToResult';
  13. /**
  14. * Delays the emission of items from the source Observable by a given time span
  15. * determined by the emissions of another Observable.
  16. *
  17. * <span class="informal">It's like {@link delay}, but the time span of the
  18. * delay duration is determined by a second Observable.</span>
  19. *
  20. * <img src="./img/delayWhen.png" width="100%">
  21. *
  22. * `delayWhen` time shifts each emitted value from the source Observable by a
  23. * time span determined by another Observable. When the source emits a value,
  24. * the `delayDurationSelector` function is called with the source value as
  25. * argument, and should return an Observable, called the "duration" Observable.
  26. * The source value is emitted on the output Observable only when the duration
  27. * Observable emits a value or completes.
  28. *
  29. * Optionally, `delayWhen` takes a second argument, `subscriptionDelay`, which
  30. * is an Observable. When `subscriptionDelay` emits its first value or
  31. * completes, the source Observable is subscribed to and starts behaving like
  32. * described in the previous paragraph. If `subscriptionDelay` is not provided,
  33. * `delayWhen` will subscribe to the source Observable as soon as the output
  34. * Observable is subscribed.
  35. *
  36. * @example <caption>Delay each click by a random amount of time, between 0 and 5 seconds</caption>
  37. * var clicks = Rx.Observable.fromEvent(document, 'click');
  38. * var delayedClicks = clicks.delayWhen(event =>
  39. * Rx.Observable.interval(Math.random() * 5000)
  40. * );
  41. * delayedClicks.subscribe(x => console.log(x));
  42. *
  43. * @see {@link debounce}
  44. * @see {@link delay}
  45. *
  46. * @param {function(value: T): Observable} delayDurationSelector A function that
  47. * returns an Observable for each value emitted by the source Observable, which
  48. * is then used to delay the emission of that item on the output Observable
  49. * until the Observable returned from this function emits a value.
  50. * @param {Observable} subscriptionDelay An Observable that triggers the
  51. * subscription to the source Observable once it emits any value.
  52. * @return {Observable} An Observable that delays the emissions of the source
  53. * Observable by an amount of time specified by the Observable returned by
  54. * `delayDurationSelector`.
  55. * @method delayWhen
  56. * @owner Observable
  57. */
  58. export function delayWhen(delayDurationSelector, subscriptionDelay) {
  59. if (subscriptionDelay) {
  60. return function (source) {
  61. return new SubscriptionDelayObservable(source, subscriptionDelay)
  62. .lift(new DelayWhenOperator(delayDurationSelector));
  63. };
  64. }
  65. return function (source) { return source.lift(new DelayWhenOperator(delayDurationSelector)); };
  66. }
  67. var DelayWhenOperator = /*@__PURE__*/ (/*@__PURE__*/ function () {
  68. function DelayWhenOperator(delayDurationSelector) {
  69. this.delayDurationSelector = delayDurationSelector;
  70. }
  71. DelayWhenOperator.prototype.call = function (subscriber, source) {
  72. return source.subscribe(new DelayWhenSubscriber(subscriber, this.delayDurationSelector));
  73. };
  74. return DelayWhenOperator;
  75. }());
  76. /**
  77. * We need this JSDoc comment for affecting ESDoc.
  78. * @ignore
  79. * @extends {Ignored}
  80. */
  81. var DelayWhenSubscriber = /*@__PURE__*/ (/*@__PURE__*/ function (_super) {
  82. __extends(DelayWhenSubscriber, _super);
  83. function DelayWhenSubscriber(destination, delayDurationSelector) {
  84. _super.call(this, destination);
  85. this.delayDurationSelector = delayDurationSelector;
  86. this.completed = false;
  87. this.delayNotifierSubscriptions = [];
  88. this.values = [];
  89. }
  90. DelayWhenSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) {
  91. this.destination.next(outerValue);
  92. this.removeSubscription(innerSub);
  93. this.tryComplete();
  94. };
  95. DelayWhenSubscriber.prototype.notifyError = function (error, innerSub) {
  96. this._error(error);
  97. };
  98. DelayWhenSubscriber.prototype.notifyComplete = function (innerSub) {
  99. var value = this.removeSubscription(innerSub);
  100. if (value) {
  101. this.destination.next(value);
  102. }
  103. this.tryComplete();
  104. };
  105. DelayWhenSubscriber.prototype._next = function (value) {
  106. try {
  107. var delayNotifier = this.delayDurationSelector(value);
  108. if (delayNotifier) {
  109. this.tryDelay(delayNotifier, value);
  110. }
  111. }
  112. catch (err) {
  113. this.destination.error(err);
  114. }
  115. };
  116. DelayWhenSubscriber.prototype._complete = function () {
  117. this.completed = true;
  118. this.tryComplete();
  119. };
  120. DelayWhenSubscriber.prototype.removeSubscription = function (subscription) {
  121. subscription.unsubscribe();
  122. var subscriptionIdx = this.delayNotifierSubscriptions.indexOf(subscription);
  123. var value = null;
  124. if (subscriptionIdx !== -1) {
  125. value = this.values[subscriptionIdx];
  126. this.delayNotifierSubscriptions.splice(subscriptionIdx, 1);
  127. this.values.splice(subscriptionIdx, 1);
  128. }
  129. return value;
  130. };
  131. DelayWhenSubscriber.prototype.tryDelay = function (delayNotifier, value) {
  132. var notifierSubscription = subscribeToResult(this, delayNotifier, value);
  133. if (notifierSubscription && !notifierSubscription.closed) {
  134. this.add(notifierSubscription);
  135. this.delayNotifierSubscriptions.push(notifierSubscription);
  136. }
  137. this.values.push(value);
  138. };
  139. DelayWhenSubscriber.prototype.tryComplete = function () {
  140. if (this.completed && this.delayNotifierSubscriptions.length === 0) {
  141. this.destination.complete();
  142. }
  143. };
  144. return DelayWhenSubscriber;
  145. }(OuterSubscriber));
  146. /**
  147. * We need this JSDoc comment for affecting ESDoc.
  148. * @ignore
  149. * @extends {Ignored}
  150. */
  151. var SubscriptionDelayObservable = /*@__PURE__*/ (/*@__PURE__*/ function (_super) {
  152. __extends(SubscriptionDelayObservable, _super);
  153. function SubscriptionDelayObservable(/** @deprecated internal use only */ source, subscriptionDelay) {
  154. _super.call(this);
  155. this.source = source;
  156. this.subscriptionDelay = subscriptionDelay;
  157. }
  158. /** @deprecated internal use only */ SubscriptionDelayObservable.prototype._subscribe = function (subscriber) {
  159. this.subscriptionDelay.subscribe(new SubscriptionDelaySubscriber(subscriber, this.source));
  160. };
  161. return SubscriptionDelayObservable;
  162. }(Observable));
  163. /**
  164. * We need this JSDoc comment for affecting ESDoc.
  165. * @ignore
  166. * @extends {Ignored}
  167. */
  168. var SubscriptionDelaySubscriber = /*@__PURE__*/ (/*@__PURE__*/ function (_super) {
  169. __extends(SubscriptionDelaySubscriber, _super);
  170. function SubscriptionDelaySubscriber(parent, source) {
  171. _super.call(this);
  172. this.parent = parent;
  173. this.source = source;
  174. this.sourceSubscribed = false;
  175. }
  176. SubscriptionDelaySubscriber.prototype._next = function (unused) {
  177. this.subscribeToSource();
  178. };
  179. SubscriptionDelaySubscriber.prototype._error = function (err) {
  180. this.unsubscribe();
  181. this.parent.error(err);
  182. };
  183. SubscriptionDelaySubscriber.prototype._complete = function () {
  184. this.subscribeToSource();
  185. };
  186. SubscriptionDelaySubscriber.prototype.subscribeToSource = function () {
  187. if (!this.sourceSubscribed) {
  188. this.sourceSubscribed = true;
  189. this.unsubscribe();
  190. this.source.subscribe(this.parent);
  191. }
  192. };
  193. return SubscriptionDelaySubscriber;
  194. }(Subscriber));
  195. //# sourceMappingURL=delayWhen.js.map