refCount.js 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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 Subscriber_1 = require('../Subscriber');
  8. function refCount() {
  9. return function refCountOperatorFunction(source) {
  10. return source.lift(new RefCountOperator(source));
  11. };
  12. }
  13. exports.refCount = refCount;
  14. var RefCountOperator = (function () {
  15. function RefCountOperator(connectable) {
  16. this.connectable = connectable;
  17. }
  18. RefCountOperator.prototype.call = function (subscriber, source) {
  19. var connectable = this.connectable;
  20. connectable._refCount++;
  21. var refCounter = new RefCountSubscriber(subscriber, connectable);
  22. var subscription = source.subscribe(refCounter);
  23. if (!refCounter.closed) {
  24. refCounter.connection = connectable.connect();
  25. }
  26. return subscription;
  27. };
  28. return RefCountOperator;
  29. }());
  30. var RefCountSubscriber = (function (_super) {
  31. __extends(RefCountSubscriber, _super);
  32. function RefCountSubscriber(destination, connectable) {
  33. _super.call(this, destination);
  34. this.connectable = connectable;
  35. }
  36. /** @deprecated internal use only */ RefCountSubscriber.prototype._unsubscribe = function () {
  37. var connectable = this.connectable;
  38. if (!connectable) {
  39. this.connection = null;
  40. return;
  41. }
  42. this.connectable = null;
  43. var refCount = connectable._refCount;
  44. if (refCount <= 0) {
  45. this.connection = null;
  46. return;
  47. }
  48. connectable._refCount = refCount - 1;
  49. if (refCount > 1) {
  50. this.connection = null;
  51. return;
  52. }
  53. ///
  54. // Compare the local RefCountSubscriber's connection Subscription to the
  55. // connection Subscription on the shared ConnectableObservable. In cases
  56. // where the ConnectableObservable source synchronously emits values, and
  57. // the RefCountSubscriber's downstream Observers synchronously unsubscribe,
  58. // execution continues to here before the RefCountOperator has a chance to
  59. // supply the RefCountSubscriber with the shared connection Subscription.
  60. // For example:
  61. // ```
  62. // Observable.range(0, 10)
  63. // .publish()
  64. // .refCount()
  65. // .take(5)
  66. // .subscribe();
  67. // ```
  68. // In order to account for this case, RefCountSubscriber should only dispose
  69. // the ConnectableObservable's shared connection Subscription if the
  70. // connection Subscription exists, *and* either:
  71. // a. RefCountSubscriber doesn't have a reference to the shared connection
  72. // Subscription yet, or,
  73. // b. RefCountSubscriber's connection Subscription reference is identical
  74. // to the shared connection Subscription
  75. ///
  76. var connection = this.connection;
  77. var sharedConnection = connectable._connection;
  78. this.connection = null;
  79. if (sharedConnection && (!connection || sharedConnection === connection)) {
  80. sharedConnection.unsubscribe();
  81. }
  82. };
  83. return RefCountSubscriber;
  84. }(Subscriber_1.Subscriber));
  85. //# sourceMappingURL=refCount.js.map