multicast.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. var operators_1 = require("rxjs/operators");
  4. /* tslint:enable:max-line-length */
  5. /**
  6. * Allows source Observable to be subscribed only once with a Subject of choice,
  7. * while still sharing its values between multiple subscribers.
  8. *
  9. * <span class="informal">Subscribe to Observable once, but send its values to multiple subscribers.</span>
  10. *
  11. * <img src="./img/multicast.png" width="100%">
  12. *
  13. * `multicast` is an operator that works in two modes.
  14. *
  15. * In the first mode you provide a single argument to it, which can be either an initialized Subject or a Subject
  16. * factory. As a result you will get a special kind of an Observable - a {@link ConnectableObservable}. It can be
  17. * subscribed multiple times, just as regular Observable, but it won't subscribe to the source Observable at that
  18. * moment. It will do it only if you call its `connect` method. This means you can essentially control by hand, when
  19. * source Observable will be actually subscribed. What is more, ConnectableObservable will share this one subscription
  20. * between all of its subscribers. This means that, for example, `ajax` Observable will only send a request once,
  21. * even though usually it would send a request per every subscriber. Since it sends a request at the moment of
  22. * subscription, here request would be sent when the `connect` method of a ConnectableObservable is called.
  23. *
  24. * The most common pattern of using ConnectableObservable is calling `connect` when the first consumer subscribes,
  25. * keeping the subscription alive while several consumers come and go and finally unsubscribing from the source
  26. * Observable, when the last consumer unsubscribes. To not implement that logic over and over again,
  27. * ConnectableObservable has a special operator, `refCount`. When called, it returns an Observable, which will count
  28. * the number of consumers subscribed to it and keep ConnectableObservable connected as long as there is at least
  29. * one consumer. So if you don't actually need to decide yourself when to connect and disconnect a
  30. * ConnectableObservable, use `refCount`.
  31. *
  32. * The second mode is invoked by calling `multicast` with an additional, second argument - selector function.
  33. * This function accepts an Observable - which basically mirrors the source Observable - and returns Observable
  34. * as well, which should be the input stream modified by any operators you want. Note that in this
  35. * mode you cannot provide initialized Subject as a first argument - it has to be a Subject factory. If
  36. * you provide selector function, `multicast` returns just a regular Observable, instead of ConnectableObservable.
  37. * Thus, as usual, each subscription to this stream triggers subscription to the source Observable. However,
  38. * if inside the selector function you subscribe to the input Observable multiple times, actual source stream
  39. * will be subscribed only once. So if you have a chain of operators that use some Observable many times,
  40. * but you want to subscribe to that Observable only once, this is the mode you would use.
  41. *
  42. * Subject provided as a first parameter of `multicast` is used as a proxy for the single subscription to the
  43. * source Observable. It means that all values from the source stream go through that Subject. Thus, if a Subject
  44. * has some special properties, Observable returned by `multicast` will have them as well. If you want to use
  45. * `multicast` with a Subject that is one of the ones included in RxJS by default - {@link Subject},
  46. * {@link AsyncSubject}, {@link BehaviorSubject}, or {@link ReplaySubject} - simply use {@link publish},
  47. * {@link publishLast}, {@link publishBehavior} or {@link publishReplay} respectively. These are actually
  48. * just wrappers around `multicast`, with a specific Subject hardcoded inside.
  49. *
  50. * Also, if you use {@link publish} or {@link publishReplay} with a ConnectableObservables `refCount` operator,
  51. * you can simply use {@link share} and {@link shareReplay} respectively, which chain these two.
  52. *
  53. * @example <caption>Use ConnectableObservable</caption>
  54. * const seconds = Rx.Observable.interval(1000);
  55. * const connectableSeconds = seconds.multicast(new Subject());
  56. *
  57. * connectableSeconds.subscribe(value => console.log('first: ' + value));
  58. * connectableSeconds.subscribe(value => console.log('second: ' + value));
  59. *
  60. * // At this point still nothing happens, even though we subscribed twice.
  61. *
  62. * connectableSeconds.connect();
  63. *
  64. * // From now on `seconds` are being logged to the console,
  65. * // twice per every second. `seconds` Observable was however only subscribed once,
  66. * // so under the hood Observable.interval had only one clock started.
  67. *
  68. * @example <caption>Use selector</caption>
  69. * const seconds = Rx.Observable.interval(1000);
  70. *
  71. * seconds
  72. * .multicast(
  73. * () => new Subject(),
  74. * seconds => seconds.zip(seconds) // Usually zip would subscribe to `seconds` twice.
  75. * // Because we are inside selector, `seconds` is subscribed once,
  76. * ) // thus starting only one clock used internally by Observable.interval.
  77. * .subscribe();
  78. *
  79. * @see {@link publish}
  80. * @see {@link publishLast}
  81. * @see {@link publishBehavior}
  82. * @see {@link publishReplay}
  83. * @see {@link share}
  84. * @see {@link shareReplay}
  85. *
  86. * @param {Function|Subject} subjectOrSubjectFactory - Factory function to create an intermediate Subject through
  87. * which the source sequence's elements will be multicast to the selector function input Observable or
  88. * ConnectableObservable returned by the operator.
  89. * @param {Function} [selector] - Optional selector function that can use the input stream
  90. * as many times as needed, without causing multiple subscriptions to the source stream.
  91. * Subscribers to the input source will receive all notifications of the source from the
  92. * time of the subscription forward.
  93. * @return {Observable<T>|ConnectableObservable<T>} An Observable that emits the results of invoking the selector
  94. * on the source stream or a special {@link ConnectableObservable}, if selector was not provided.
  95. *
  96. * @method multicast
  97. * @owner Observable
  98. */
  99. function multicast(subjectOrSubjectFactory, selector) {
  100. return operators_1.multicast(subjectOrSubjectFactory, selector)(this);
  101. }
  102. exports.multicast = multicast;
  103. //# sourceMappingURL=multicast.js.map