windowWhen.js 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /** PURE_IMPORTS_START .._Subject,.._util_tryCatch,.._util_errorObject,.._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 { Subject } from '../Subject';
  10. import { tryCatch } from '../util/tryCatch';
  11. import { errorObject } from '../util/errorObject';
  12. import { OuterSubscriber } from '../OuterSubscriber';
  13. import { subscribeToResult } from '../util/subscribeToResult';
  14. /**
  15. * Branch out the source Observable values as a nested Observable using a
  16. * factory function of closing Observables to determine when to start a new
  17. * window.
  18. *
  19. * <span class="informal">It's like {@link bufferWhen}, but emits a nested
  20. * Observable instead of an array.</span>
  21. *
  22. * <img src="./img/windowWhen.png" width="100%">
  23. *
  24. * Returns an Observable that emits windows of items it collects from the source
  25. * Observable. The output Observable emits connected, non-overlapping windows.
  26. * It emits the current window and opens a new one whenever the Observable
  27. * produced by the specified `closingSelector` function emits an item. The first
  28. * window is opened immediately when subscribing to the output Observable.
  29. *
  30. * @example <caption>Emit only the first two clicks events in every window of [1-5] random seconds</caption>
  31. * var clicks = Rx.Observable.fromEvent(document, 'click');
  32. * var result = clicks
  33. * .windowWhen(() => Rx.Observable.interval(1000 + Math.random() * 4000))
  34. * .map(win => win.take(2)) // each window has at most 2 emissions
  35. * .mergeAll(); // flatten the Observable-of-Observables
  36. * result.subscribe(x => console.log(x));
  37. *
  38. * @see {@link window}
  39. * @see {@link windowCount}
  40. * @see {@link windowTime}
  41. * @see {@link windowToggle}
  42. * @see {@link bufferWhen}
  43. *
  44. * @param {function(): Observable} closingSelector A function that takes no
  45. * arguments and returns an Observable that signals (on either `next` or
  46. * `complete`) when to close the previous window and start a new one.
  47. * @return {Observable<Observable<T>>} An observable of windows, which in turn
  48. * are Observables.
  49. * @method windowWhen
  50. * @owner Observable
  51. */
  52. export function windowWhen(closingSelector) {
  53. return function windowWhenOperatorFunction(source) {
  54. return source.lift(new WindowOperator(closingSelector));
  55. };
  56. }
  57. var WindowOperator = /*@__PURE__*/ (/*@__PURE__*/ function () {
  58. function WindowOperator(closingSelector) {
  59. this.closingSelector = closingSelector;
  60. }
  61. WindowOperator.prototype.call = function (subscriber, source) {
  62. return source.subscribe(new WindowSubscriber(subscriber, this.closingSelector));
  63. };
  64. return WindowOperator;
  65. }());
  66. /**
  67. * We need this JSDoc comment for affecting ESDoc.
  68. * @ignore
  69. * @extends {Ignored}
  70. */
  71. var WindowSubscriber = /*@__PURE__*/ (/*@__PURE__*/ function (_super) {
  72. __extends(WindowSubscriber, _super);
  73. function WindowSubscriber(destination, closingSelector) {
  74. _super.call(this, destination);
  75. this.destination = destination;
  76. this.closingSelector = closingSelector;
  77. this.openWindow();
  78. }
  79. WindowSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) {
  80. this.openWindow(innerSub);
  81. };
  82. WindowSubscriber.prototype.notifyError = function (error, innerSub) {
  83. this._error(error);
  84. };
  85. WindowSubscriber.prototype.notifyComplete = function (innerSub) {
  86. this.openWindow(innerSub);
  87. };
  88. WindowSubscriber.prototype._next = function (value) {
  89. this.window.next(value);
  90. };
  91. WindowSubscriber.prototype._error = function (err) {
  92. this.window.error(err);
  93. this.destination.error(err);
  94. this.unsubscribeClosingNotification();
  95. };
  96. WindowSubscriber.prototype._complete = function () {
  97. this.window.complete();
  98. this.destination.complete();
  99. this.unsubscribeClosingNotification();
  100. };
  101. WindowSubscriber.prototype.unsubscribeClosingNotification = function () {
  102. if (this.closingNotification) {
  103. this.closingNotification.unsubscribe();
  104. }
  105. };
  106. WindowSubscriber.prototype.openWindow = function (innerSub) {
  107. if (innerSub === void 0) {
  108. innerSub = null;
  109. }
  110. if (innerSub) {
  111. this.remove(innerSub);
  112. innerSub.unsubscribe();
  113. }
  114. var prevWindow = this.window;
  115. if (prevWindow) {
  116. prevWindow.complete();
  117. }
  118. var window = this.window = new Subject();
  119. this.destination.next(window);
  120. var closingNotifier = tryCatch(this.closingSelector)();
  121. if (closingNotifier === errorObject) {
  122. var err = errorObject.e;
  123. this.destination.error(err);
  124. this.window.error(err);
  125. }
  126. else {
  127. this.add(this.closingNotification = subscribeToResult(this, closingNotifier));
  128. }
  129. };
  130. return WindowSubscriber;
  131. }(OuterSubscriber));
  132. //# sourceMappingURL=windowWhen.js.map