cd48692ccd3e27579bfb55438256aa7961411dc6f53b39e7c63210fb8664fd53d8b1c745fbaf1872fbfe5c2303649ccd7620751e614aff4f12cddddf5a9f57 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import { innerFrom } from '../observable/innerFrom';
  2. import { MonoTypeOperatorFunction, ObservableInput } from '../types';
  3. import { operate } from '../util/lift';
  4. import { noop } from '../util/noop';
  5. import { createOperatorSubscriber } from './OperatorSubscriber';
  6. /**
  7. * Emits the most recently emitted value from the source Observable whenever
  8. * another Observable, the `notifier`, emits.
  9. *
  10. * <span class="informal">It's like {@link sampleTime}, but samples whenever
  11. * the `notifier` `ObservableInput` emits something.</span>
  12. *
  13. * ![](sample.png)
  14. *
  15. * Whenever the `notifier` `ObservableInput` emits a value, `sample`
  16. * looks at the source Observable and emits whichever value it has most recently
  17. * emitted since the previous sampling, unless the source has not emitted
  18. * anything since the previous sampling. The `notifier` is subscribed to as soon
  19. * as the output Observable is subscribed.
  20. *
  21. * ## Example
  22. *
  23. * On every click, sample the most recent `seconds` timer
  24. *
  25. * ```ts
  26. * import { fromEvent, interval, sample } from 'rxjs';
  27. *
  28. * const seconds = interval(1000);
  29. * const clicks = fromEvent(document, 'click');
  30. * const result = seconds.pipe(sample(clicks));
  31. *
  32. * result.subscribe(x => console.log(x));
  33. * ```
  34. *
  35. * @see {@link audit}
  36. * @see {@link debounce}
  37. * @see {@link sampleTime}
  38. * @see {@link throttle}
  39. *
  40. * @param notifier The `ObservableInput` to use for sampling the
  41. * source Observable.
  42. * @return A function that returns an Observable that emits the results of
  43. * sampling the values emitted by the source Observable whenever the notifier
  44. * Observable emits value or completes.
  45. */
  46. export function sample<T>(notifier: ObservableInput<any>): MonoTypeOperatorFunction<T> {
  47. return operate((source, subscriber) => {
  48. let hasValue = false;
  49. let lastValue: T | null = null;
  50. source.subscribe(
  51. createOperatorSubscriber(subscriber, (value) => {
  52. hasValue = true;
  53. lastValue = value;
  54. })
  55. );
  56. innerFrom(notifier).subscribe(
  57. createOperatorSubscriber(
  58. subscriber,
  59. () => {
  60. if (hasValue) {
  61. hasValue = false;
  62. const value = lastValue!;
  63. lastValue = null;
  64. subscriber.next(value);
  65. }
  66. },
  67. noop
  68. )
  69. );
  70. });
  71. }