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

Subject.ts 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. import { Operator } from './Operator';
  2. import { Observable } from './Observable';
  3. import { Subscriber } from './Subscriber';
  4. import { Subscription } from './Subscription';
  5. import { Observer, SubscriptionLike, TeardownLogic } from './types';
  6. import { ObjectUnsubscribedError } from './util/ObjectUnsubscribedError';
  7. import { SubjectSubscription } from './SubjectSubscription';
  8. import { rxSubscriber as rxSubscriberSymbol } from '../internal/symbol/rxSubscriber';
  9. /**
  10. * @class SubjectSubscriber<T>
  11. */
  12. export class SubjectSubscriber<T> extends Subscriber<T> {
  13. constructor(protected destination: Subject<T>) {
  14. super(destination);
  15. }
  16. }
  17. /**
  18. * A Subject is a special type of Observable that allows values to be
  19. * multicasted to many Observers. Subjects are like EventEmitters.
  20. *
  21. * Every Subject is an Observable and an Observer. You can subscribe to a
  22. * Subject, and you can call next to feed values as well as error and complete.
  23. *
  24. * @class Subject<T>
  25. */
  26. export class Subject<T> extends Observable<T> implements SubscriptionLike {
  27. [rxSubscriberSymbol]() {
  28. return new SubjectSubscriber(this);
  29. }
  30. observers: Observer<T>[] = [];
  31. closed = false;
  32. isStopped = false;
  33. hasError = false;
  34. thrownError: any = null;
  35. constructor() {
  36. super();
  37. }
  38. /**@nocollapse
  39. * @deprecated use new Subject() instead
  40. */
  41. static create: Function = <T>(destination: Observer<T>, source: Observable<T>): AnonymousSubject<T> => {
  42. return new AnonymousSubject<T>(destination, source);
  43. }
  44. lift<R>(operator: Operator<T, R>): Observable<R> {
  45. const subject = new AnonymousSubject(this, this);
  46. subject.operator = <any>operator;
  47. return <any>subject;
  48. }
  49. next(value?: T) {
  50. if (this.closed) {
  51. throw new ObjectUnsubscribedError();
  52. }
  53. if (!this.isStopped) {
  54. const { observers } = this;
  55. const len = observers.length;
  56. const copy = observers.slice();
  57. for (let i = 0; i < len; i++) {
  58. copy[i].next(value);
  59. }
  60. }
  61. }
  62. error(err: any) {
  63. if (this.closed) {
  64. throw new ObjectUnsubscribedError();
  65. }
  66. this.hasError = true;
  67. this.thrownError = err;
  68. this.isStopped = true;
  69. const { observers } = this;
  70. const len = observers.length;
  71. const copy = observers.slice();
  72. for (let i = 0; i < len; i++) {
  73. copy[i].error(err);
  74. }
  75. this.observers.length = 0;
  76. }
  77. complete() {
  78. if (this.closed) {
  79. throw new ObjectUnsubscribedError();
  80. }
  81. this.isStopped = true;
  82. const { observers } = this;
  83. const len = observers.length;
  84. const copy = observers.slice();
  85. for (let i = 0; i < len; i++) {
  86. copy[i].complete();
  87. }
  88. this.observers.length = 0;
  89. }
  90. unsubscribe() {
  91. this.isStopped = true;
  92. this.closed = true;
  93. this.observers = null;
  94. }
  95. /** @deprecated This is an internal implementation detail, do not use. */
  96. _trySubscribe(subscriber: Subscriber<T>): TeardownLogic {
  97. if (this.closed) {
  98. throw new ObjectUnsubscribedError();
  99. } else {
  100. return super._trySubscribe(subscriber);
  101. }
  102. }
  103. /** @deprecated This is an internal implementation detail, do not use. */
  104. _subscribe(subscriber: Subscriber<T>): Subscription {
  105. if (this.closed) {
  106. throw new ObjectUnsubscribedError();
  107. } else if (this.hasError) {
  108. subscriber.error(this.thrownError);
  109. return Subscription.EMPTY;
  110. } else if (this.isStopped) {
  111. subscriber.complete();
  112. return Subscription.EMPTY;
  113. } else {
  114. this.observers.push(subscriber);
  115. return new SubjectSubscription(this, subscriber);
  116. }
  117. }
  118. /**
  119. * Creates a new Observable with this Subject as the source. You can do this
  120. * to create customize Observer-side logic of the Subject and conceal it from
  121. * code that uses the Observable.
  122. * @return {Observable} Observable that the Subject casts to
  123. */
  124. asObservable(): Observable<T> {
  125. const observable = new Observable<T>();
  126. (<any>observable).source = this;
  127. return observable;
  128. }
  129. }
  130. /**
  131. * @class AnonymousSubject<T>
  132. */
  133. export class AnonymousSubject<T> extends Subject<T> {
  134. constructor(protected destination?: Observer<T>, source?: Observable<T>) {
  135. super();
  136. this.source = source;
  137. }
  138. next(value: T) {
  139. const { destination } = this;
  140. if (destination && destination.next) {
  141. destination.next(value);
  142. }
  143. }
  144. error(err: any) {
  145. const { destination } = this;
  146. if (destination && destination.error) {
  147. this.destination.error(err);
  148. }
  149. }
  150. complete() {
  151. const { destination } = this;
  152. if (destination && destination.complete) {
  153. this.destination.complete();
  154. }
  155. }
  156. /** @deprecated This is an internal implementation detail, do not use. */
  157. _subscribe(subscriber: Subscriber<T>): Subscription {
  158. const { source } = this;
  159. if (source) {
  160. return this.source.subscribe(subscriber);
  161. } else {
  162. return Subscription.EMPTY;
  163. }
  164. }
  165. }