7c10514383e2a6ced7d47c7fe447cf55269e521947d38dbb1a01750e16304a93e34fa3147b8d739ca083c0808659f8739009d3e4bec7dcb15185d410323090 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import { Operator } from '../Operator';
  2. import { Subscriber } from '../Subscriber';
  3. import { Observable } from '../Observable';
  4. import { OperatorFunction } from '../types';
  5. /**
  6. * Emits false if the input observable emits any values, or emits true if the
  7. * input observable completes without emitting any values.
  8. *
  9. * <span class="informal">Tells whether any values are emitted by an observable</span>
  10. *
  11. * ![](isEmpty.png)
  12. *
  13. * `isEmpty` transforms an Observable that emits values into an Observable that
  14. * emits a single boolean value representing whether or not any values were
  15. * emitted by the source Observable. As soon as the source Observable emits a
  16. * value, `isEmpty` will emit a `false` and complete. If the source Observable
  17. * completes having not emitted anything, `isEmpty` will emit a `true` and
  18. * complete.
  19. *
  20. * A similar effect could be achieved with {@link count}, but `isEmpty` can emit
  21. * a `false` value sooner.
  22. *
  23. * ## Examples
  24. *
  25. * Emit `false` for a non-empty Observable
  26. * ```javascript
  27. * import { Subject } from 'rxjs';
  28. * import { isEmpty } from 'rxjs/operators';
  29. *
  30. * const source = new Subject<string>();
  31. * const result = source.pipe(isEmpty());
  32. * source.subscribe(x => console.log(x));
  33. * result.subscribe(x => console.log(x));
  34. * source.next('a');
  35. * source.next('b');
  36. * source.next('c');
  37. * source.complete();
  38. *
  39. * // Results in:
  40. * // a
  41. * // false
  42. * // b
  43. * // c
  44. * ```
  45. *
  46. * Emit `true` for an empty Observable
  47. * ```javascript
  48. * import { EMPTY } from 'rxjs';
  49. * import { isEmpty } from 'rxjs/operators';
  50. *
  51. * const result = EMPTY.pipe(isEmpty());
  52. * result.subscribe(x => console.log(x));
  53. * // Results in:
  54. * // true
  55. * ```
  56. *
  57. * @see {@link count}
  58. * @see {@link EMPTY}
  59. *
  60. * @return {OperatorFunction<T, boolean>} An Observable of a boolean value indicating whether observable was empty or not
  61. * @method isEmpty
  62. * @owner Observable
  63. */
  64. export function isEmpty<T>(): OperatorFunction<T, boolean> {
  65. return (source: Observable<T>) => source.lift(new IsEmptyOperator());
  66. }
  67. class IsEmptyOperator implements Operator<any, boolean> {
  68. call (observer: Subscriber<boolean>, source: any): any {
  69. return source.subscribe(new IsEmptySubscriber(observer));
  70. }
  71. }
  72. /**
  73. * We need this JSDoc comment for affecting ESDoc.
  74. * @ignore
  75. * @extends {Ignored}
  76. */
  77. class IsEmptySubscriber extends Subscriber<any> {
  78. constructor(destination: Subscriber<boolean>) {
  79. super(destination);
  80. }
  81. private notifyComplete(isEmpty: boolean): void {
  82. const destination = this.destination;
  83. destination.next(isEmpty);
  84. destination.complete();
  85. }
  86. protected _next(value: boolean) {
  87. this.notifyComplete(false);
  88. }
  89. protected _complete() {
  90. this.notifyComplete(true);
  91. }
  92. }