Repositorio del curso CCOM4030 el semestre B91 del proyecto Artesanías con el Instituto de Cultura

withLatestFrom.ts 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import { Operator } from '../Operator';
  2. import { Subscriber } from '../Subscriber';
  3. import { Observable } from '../Observable';
  4. import { OuterSubscriber } from '../OuterSubscriber';
  5. import { InnerSubscriber } from '../InnerSubscriber';
  6. import { subscribeToResult } from '../util/subscribeToResult';
  7. import { ObservableInput, OperatorFunction, ObservedValueOf } from '../types';
  8. /* tslint:disable:max-line-length */
  9. export function withLatestFrom<T, R>(project: (v1: T) => R): OperatorFunction<T, R>;
  10. export function withLatestFrom<T, O2 extends ObservableInput<any>, R>(source2: O2, project: (v1: T, v2: ObservedValueOf<O2>) => R): OperatorFunction<T, R>;
  11. export function withLatestFrom<T, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, R>(v2: O2, v3: O3, project: (v1: T, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>) => R): OperatorFunction<T, R>;
  12. export function withLatestFrom<T, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, R>(v2: O2, v3: O3, v4: O4, project: (v1: T, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>) => R): OperatorFunction<T, R>;
  13. export function withLatestFrom<T, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, O5 extends ObservableInput<any>, R>(v2: O2, v3: O3, v4: O4, v5: O5, project: (v1: T, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>, v5: ObservedValueOf<O5>) => R): OperatorFunction<T, R>;
  14. export function withLatestFrom<T, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, O5 extends ObservableInput<any>, O6 extends ObservableInput<any>, R>(v2: O2, v3: O3, v4: O4, v5: O5, v6: O6, project: (v1: T, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>, v5: ObservedValueOf<O5>, v6: ObservedValueOf<O6>) => R): OperatorFunction<T, R>;
  15. export function withLatestFrom<T, O2 extends ObservableInput<any>>(source2: O2): OperatorFunction<T, [T, ObservedValueOf<O2>]>;
  16. export function withLatestFrom<T, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>>(v2: O2, v3: O3): OperatorFunction<T, [T, ObservedValueOf<O2>, ObservedValueOf<O3>]>;
  17. export function withLatestFrom<T, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>>(v2: O2, v3: O3, v4: O4): OperatorFunction<T, [T, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>]>;
  18. export function withLatestFrom<T, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, O5 extends ObservableInput<any>>(v2: O2, v3: O3, v4: O4, v5: O5): OperatorFunction<T, [T, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>]>;
  19. export function withLatestFrom<T, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, O5 extends ObservableInput<any>, O6 extends ObservableInput<any>>(v2: O2, v3: O3, v4: O4, v5: O5, v6: O6): OperatorFunction<T, [T, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>, ObservedValueOf<O6>]>;
  20. export function withLatestFrom<T, R>(...observables: Array<ObservableInput<any> | ((...values: Array<any>) => R)>): OperatorFunction<T, R>;
  21. export function withLatestFrom<T, R>(array: ObservableInput<any>[]): OperatorFunction<T, R>;
  22. export function withLatestFrom<T, R>(array: ObservableInput<any>[], project: (...values: Array<any>) => R): OperatorFunction<T, R>;
  23. /* tslint:enable:max-line-length */
  24. /**
  25. * Combines the source Observable with other Observables to create an Observable
  26. * whose values are calculated from the latest values of each, only when the
  27. * source emits.
  28. *
  29. * <span class="informal">Whenever the source Observable emits a value, it
  30. * computes a formula using that value plus the latest values from other input
  31. * Observables, then emits the output of that formula.</span>
  32. *
  33. * ![](withLatestFrom.png)
  34. *
  35. * `withLatestFrom` combines each value from the source Observable (the
  36. * instance) with the latest values from the other input Observables only when
  37. * the source emits a value, optionally using a `project` function to determine
  38. * the value to be emitted on the output Observable. All input Observables must
  39. * emit at least one value before the output Observable will emit a value.
  40. *
  41. * ## Example
  42. * On every click event, emit an array with the latest timer event plus the click event
  43. * ```ts
  44. * import { fromEvent, interval } from 'rxjs';
  45. * import { withLatestFrom } from 'rxjs/operators';
  46. *
  47. * const clicks = fromEvent(document, 'click');
  48. * const timer = interval(1000);
  49. * const result = clicks.pipe(withLatestFrom(timer));
  50. * result.subscribe(x => console.log(x));
  51. * ```
  52. *
  53. * @see {@link combineLatest}
  54. *
  55. * @param {ObservableInput} other An input Observable to combine with the source
  56. * Observable. More than one input Observables may be given as argument.
  57. * @param {Function} [project] Projection function for combining values
  58. * together. Receives all values in order of the Observables passed, where the
  59. * first parameter is a value from the source Observable. (e.g.
  60. * `a.pipe(withLatestFrom(b, c), map(([a1, b1, c1]) => a1 + b1 + c1))`). If this is not
  61. * passed, arrays will be emitted on the output Observable.
  62. * @return {Observable} An Observable of projected values from the most recent
  63. * values from each input Observable, or an array of the most recent values from
  64. * each input Observable.
  65. * @method withLatestFrom
  66. * @owner Observable
  67. */
  68. export function withLatestFrom<T, R>(...args: Array<ObservableInput<any> | ((...values: Array<any>) => R)>): OperatorFunction<T, R> {
  69. return (source: Observable<T>) => {
  70. let project: any;
  71. if (typeof args[args.length - 1] === 'function') {
  72. project = args.pop();
  73. }
  74. const observables = <Observable<any>[]>args;
  75. return source.lift(new WithLatestFromOperator(observables, project));
  76. };
  77. }
  78. class WithLatestFromOperator<T, R> implements Operator<T, R> {
  79. constructor(private observables: Observable<any>[],
  80. private project?: (...values: any[]) => Observable<R>) {
  81. }
  82. call(subscriber: Subscriber<R>, source: any): any {
  83. return source.subscribe(new WithLatestFromSubscriber(subscriber, this.observables, this.project));
  84. }
  85. }
  86. /**
  87. * We need this JSDoc comment for affecting ESDoc.
  88. * @ignore
  89. * @extends {Ignored}
  90. */
  91. class WithLatestFromSubscriber<T, R> extends OuterSubscriber<T, R> {
  92. private values: any[];
  93. private toRespond: number[] = [];
  94. constructor(destination: Subscriber<R>,
  95. private observables: Observable<any>[],
  96. private project?: (...values: any[]) => Observable<R>) {
  97. super(destination);
  98. const len = observables.length;
  99. this.values = new Array(len);
  100. for (let i = 0; i < len; i++) {
  101. this.toRespond.push(i);
  102. }
  103. for (let i = 0; i < len; i++) {
  104. let observable = observables[i];
  105. this.add(subscribeToResult<T, R>(this, observable, undefined, i));
  106. }
  107. }
  108. notifyNext(_outerValue: T, innerValue: R,
  109. outerIndex: number): void {
  110. this.values[outerIndex] = innerValue;
  111. const toRespond = this.toRespond;
  112. if (toRespond.length > 0) {
  113. const found = toRespond.indexOf(outerIndex);
  114. if (found !== -1) {
  115. toRespond.splice(found, 1);
  116. }
  117. }
  118. }
  119. notifyComplete() {
  120. // noop
  121. }
  122. protected _next(value: T) {
  123. if (this.toRespond.length === 0) {
  124. const args = [value, ...this.values];
  125. if (this.project) {
  126. this._tryProject(args);
  127. } else {
  128. this.destination.next!(args);
  129. }
  130. }
  131. }
  132. private _tryProject(args: any[]) {
  133. let result: any;
  134. try {
  135. result = this.project!.apply(this, args);
  136. } catch (err) {
  137. this.destination.error!(err);
  138. return;
  139. }
  140. this.destination.next!(result);
  141. }
  142. }