withLatestFrom.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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. /* tslint:enable:max-line-length */
  10. /**
  11. * Combines the source Observable with other Observables to create an Observable
  12. * whose values are calculated from the latest values of each, only when the
  13. * source emits.
  14. *
  15. * <span class="informal">Whenever the source Observable emits a value, it
  16. * computes a formula using that value plus the latest values from other input
  17. * Observables, then emits the output of that formula.</span>
  18. *
  19. * <img src="./img/withLatestFrom.png" width="100%">
  20. *
  21. * `withLatestFrom` combines each value from the source Observable (the
  22. * instance) with the latest values from the other input Observables only when
  23. * the source emits a value, optionally using a `project` function to determine
  24. * the value to be emitted on the output Observable. All input Observables must
  25. * emit at least one value before the output Observable will emit a value.
  26. *
  27. * @example <caption>On every click event, emit an array with the latest timer event plus the click event</caption>
  28. * var clicks = Rx.Observable.fromEvent(document, 'click');
  29. * var timer = Rx.Observable.interval(1000);
  30. * var result = clicks.withLatestFrom(timer);
  31. * result.subscribe(x => console.log(x));
  32. *
  33. * @see {@link combineLatest}
  34. *
  35. * @param {ObservableInput} other An input Observable to combine with the source
  36. * Observable. More than one input Observables may be given as argument.
  37. * @param {Function} [project] Projection function for combining values
  38. * together. Receives all values in order of the Observables passed, where the
  39. * first parameter is a value from the source Observable. (e.g.
  40. * `a.withLatestFrom(b, c, (a1, b1, c1) => a1 + b1 + c1)`). If this is not
  41. * passed, arrays will be emitted on the output Observable.
  42. * @return {Observable} An Observable of projected values from the most recent
  43. * values from each input Observable, or an array of the most recent values from
  44. * each input Observable.
  45. * @method withLatestFrom
  46. * @owner Observable
  47. */
  48. function withLatestFrom() {
  49. var args = [];
  50. for (var _i = 0; _i < arguments.length; _i++) {
  51. args[_i - 0] = arguments[_i];
  52. }
  53. return function (source) {
  54. var project;
  55. if (typeof args[args.length - 1] === 'function') {
  56. project = args.pop();
  57. }
  58. var observables = args;
  59. return source.lift(new WithLatestFromOperator(observables, project));
  60. };
  61. }
  62. exports.withLatestFrom = withLatestFrom;
  63. var WithLatestFromOperator = (function () {
  64. function WithLatestFromOperator(observables, project) {
  65. this.observables = observables;
  66. this.project = project;
  67. }
  68. WithLatestFromOperator.prototype.call = function (subscriber, source) {
  69. return source.subscribe(new WithLatestFromSubscriber(subscriber, this.observables, this.project));
  70. };
  71. return WithLatestFromOperator;
  72. }());
  73. /**
  74. * We need this JSDoc comment for affecting ESDoc.
  75. * @ignore
  76. * @extends {Ignored}
  77. */
  78. var WithLatestFromSubscriber = (function (_super) {
  79. __extends(WithLatestFromSubscriber, _super);
  80. function WithLatestFromSubscriber(destination, observables, project) {
  81. _super.call(this, destination);
  82. this.observables = observables;
  83. this.project = project;
  84. this.toRespond = [];
  85. var len = observables.length;
  86. this.values = new Array(len);
  87. for (var i = 0; i < len; i++) {
  88. this.toRespond.push(i);
  89. }
  90. for (var i = 0; i < len; i++) {
  91. var observable = observables[i];
  92. this.add(subscribeToResult_1.subscribeToResult(this, observable, observable, i));
  93. }
  94. }
  95. WithLatestFromSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) {
  96. this.values[outerIndex] = innerValue;
  97. var toRespond = this.toRespond;
  98. if (toRespond.length > 0) {
  99. var found = toRespond.indexOf(outerIndex);
  100. if (found !== -1) {
  101. toRespond.splice(found, 1);
  102. }
  103. }
  104. };
  105. WithLatestFromSubscriber.prototype.notifyComplete = function () {
  106. // noop
  107. };
  108. WithLatestFromSubscriber.prototype._next = function (value) {
  109. if (this.toRespond.length === 0) {
  110. var args = [value].concat(this.values);
  111. if (this.project) {
  112. this._tryProject(args);
  113. }
  114. else {
  115. this.destination.next(args);
  116. }
  117. }
  118. };
  119. WithLatestFromSubscriber.prototype._tryProject = function (args) {
  120. var result;
  121. try {
  122. result = this.project.apply(this, args);
  123. }
  124. catch (err) {
  125. this.destination.error(err);
  126. return;
  127. }
  128. this.destination.next(result);
  129. };
  130. return WithLatestFromSubscriber;
  131. }(OuterSubscriber_1.OuterSubscriber));
  132. //# sourceMappingURL=withLatestFrom.js.map