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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. import { Operator } from './Operator';
  2. import { Subscriber } from './Subscriber';
  3. import { Subscription } from './Subscription';
  4. import { TeardownLogic, OperatorFunction, PartialObserver, Subscribable } from './types';
  5. import { canReportError } from './util/canReportError';
  6. import { toSubscriber } from './util/toSubscriber';
  7. import { iif } from './observable/iif';
  8. import { throwError } from './observable/throwError';
  9. import { observable as Symbol_observable } from './symbol/observable';
  10. import { pipeFromArray } from './util/pipe';
  11. import { config } from './config';
  12. /**
  13. * A representation of any set of values over any amount of time. This is the most basic building block
  14. * of RxJS.
  15. *
  16. * @class Observable<T>
  17. */
  18. export class Observable<T> implements Subscribable<T> {
  19. /** Internal implementation detail, do not use directly. */
  20. public _isScalar: boolean = false;
  21. /** @deprecated This is an internal implementation detail, do not use. */
  22. source: Observable<any>;
  23. /** @deprecated This is an internal implementation detail, do not use. */
  24. operator: Operator<any, T>;
  25. /**
  26. * @constructor
  27. * @param {Function} subscribe the function that is called when the Observable is
  28. * initially subscribed to. This function is given a Subscriber, to which new values
  29. * can be `next`ed, or an `error` method can be called to raise an error, or
  30. * `complete` can be called to notify of a successful completion.
  31. */
  32. constructor(subscribe?: (this: Observable<T>, subscriber: Subscriber<T>) => TeardownLogic) {
  33. if (subscribe) {
  34. this._subscribe = subscribe;
  35. }
  36. }
  37. // HACK: Since TypeScript inherits static properties too, we have to
  38. // fight against TypeScript here so Subject can have a different static create signature
  39. /**
  40. * Creates a new cold Observable by calling the Observable constructor
  41. * @static true
  42. * @owner Observable
  43. * @method create
  44. * @param {Function} subscribe? the subscriber function to be passed to the Observable constructor
  45. * @return {Observable} a new cold observable
  46. * @nocollapse
  47. * @deprecated use new Observable() instead
  48. */
  49. static create: Function = <T>(subscribe?: (subscriber: Subscriber<T>) => TeardownLogic) => {
  50. return new Observable<T>(subscribe);
  51. }
  52. /**
  53. * Creates a new Observable, with this Observable as the source, and the passed
  54. * operator defined as the new observable's operator.
  55. * @method lift
  56. * @param {Operator} operator the operator defining the operation to take on the observable
  57. * @return {Observable} a new observable with the Operator applied
  58. */
  59. lift<R>(operator: Operator<T, R>): Observable<R> {
  60. const observable = new Observable<R>();
  61. observable.source = this;
  62. observable.operator = operator;
  63. return observable;
  64. }
  65. subscribe(observer?: PartialObserver<T>): Subscription;
  66. /** @deprecated Use an observer instead of a complete callback */
  67. subscribe(next: null | undefined, error: null | undefined, complete: () => void): Subscription;
  68. /** @deprecated Use an observer instead of an error callback */
  69. subscribe(next: null | undefined, error: (error: any) => void, complete?: () => void): Subscription;
  70. /** @deprecated Use an observer instead of a complete callback */
  71. subscribe(next: (value: T) => void, error: null | undefined, complete: () => void): Subscription;
  72. subscribe(next?: (value: T) => void, error?: (error: any) => void, complete?: () => void): Subscription;
  73. /**
  74. * Invokes an execution of an Observable and registers Observer handlers for notifications it will emit.
  75. *
  76. * <span class="informal">Use it when you have all these Observables, but still nothing is happening.</span>
  77. *
  78. * `subscribe` is not a regular operator, but a method that calls Observable's internal `subscribe` function. It
  79. * might be for example a function that you passed to Observable's constructor, but most of the time it is
  80. * a library implementation, which defines what will be emitted by an Observable, and when it be will emitted. This means
  81. * that calling `subscribe` is actually the moment when Observable starts its work, not when it is created, as it is often
  82. * the thought.
  83. *
  84. * Apart from starting the execution of an Observable, this method allows you to listen for values
  85. * that an Observable emits, as well as for when it completes or errors. You can achieve this in two
  86. * of the following ways.
  87. *
  88. * The first way is creating an object that implements {@link Observer} interface. It should have methods
  89. * defined by that interface, but note that it should be just a regular JavaScript object, which you can create
  90. * yourself in any way you want (ES6 class, classic function constructor, object literal etc.). In particular do
  91. * not attempt to use any RxJS implementation details to create Observers - you don't need them. Remember also
  92. * that your object does not have to implement all methods. If you find yourself creating a method that doesn't
  93. * do anything, you can simply omit it. Note however, if the `error` method is not provided, all errors will
  94. * be left uncaught.
  95. *
  96. * The second way is to give up on Observer object altogether and simply provide callback functions in place of its methods.
  97. * This means you can provide three functions as arguments to `subscribe`, where the first function is equivalent
  98. * of a `next` method, the second of an `error` method and the third of a `complete` method. Just as in case of Observer,
  99. * if you do not need to listen for something, you can omit a function, preferably by passing `undefined` or `null`,
  100. * since `subscribe` recognizes these functions by where they were placed in function call. When it comes
  101. * to `error` function, just as before, if not provided, errors emitted by an Observable will be thrown.
  102. *
  103. * Whichever style of calling `subscribe` you use, in both cases it returns a Subscription object.
  104. * This object allows you to call `unsubscribe` on it, which in turn will stop the work that an Observable does and will clean
  105. * up all resources that an Observable used. Note that cancelling a subscription will not call `complete` callback
  106. * provided to `subscribe` function, which is reserved for a regular completion signal that comes from an Observable.
  107. *
  108. * Remember that callbacks provided to `subscribe` are not guaranteed to be called asynchronously.
  109. * It is an Observable itself that decides when these functions will be called. For example {@link of}
  110. * by default emits all its values synchronously. Always check documentation for how given Observable
  111. * will behave when subscribed and if its default behavior can be modified with a `scheduler`.
  112. *
  113. * ## Example
  114. * ### Subscribe with an Observer
  115. * ```ts
  116. * import { of } from 'rxjs';
  117. *
  118. * const sumObserver = {
  119. * sum: 0,
  120. * next(value) {
  121. * console.log('Adding: ' + value);
  122. * this.sum = this.sum + value;
  123. * },
  124. * error() {
  125. * // We actually could just remove this method,
  126. * // since we do not really care about errors right now.
  127. * },
  128. * complete() {
  129. * console.log('Sum equals: ' + this.sum);
  130. * }
  131. * };
  132. *
  133. * of(1, 2, 3) // Synchronously emits 1, 2, 3 and then completes.
  134. * .subscribe(sumObserver);
  135. *
  136. * // Logs:
  137. * // "Adding: 1"
  138. * // "Adding: 2"
  139. * // "Adding: 3"
  140. * // "Sum equals: 6"
  141. * ```
  142. *
  143. * ### Subscribe with functions
  144. * ```ts
  145. * import { of } from 'rxjs'
  146. *
  147. * let sum = 0;
  148. *
  149. * of(1, 2, 3).subscribe(
  150. * value => {
  151. * console.log('Adding: ' + value);
  152. * sum = sum + value;
  153. * },
  154. * undefined,
  155. * () => console.log('Sum equals: ' + sum)
  156. * );
  157. *
  158. * // Logs:
  159. * // "Adding: 1"
  160. * // "Adding: 2"
  161. * // "Adding: 3"
  162. * // "Sum equals: 6"
  163. * ```
  164. *
  165. * ### Cancel a subscription
  166. * ```ts
  167. * import { interval } from 'rxjs';
  168. *
  169. * const subscription = interval(1000).subscribe(
  170. * num => console.log(num),
  171. * undefined,
  172. * () => {
  173. * // Will not be called, even when cancelling subscription.
  174. * console.log('completed!');
  175. * }
  176. * );
  177. *
  178. * setTimeout(() => {
  179. * subscription.unsubscribe();
  180. * console.log('unsubscribed!');
  181. * }, 2500);
  182. *
  183. * // Logs:
  184. * // 0 after 1s
  185. * // 1 after 2s
  186. * // "unsubscribed!" after 2.5s
  187. * ```
  188. *
  189. * @param {Observer|Function} observerOrNext (optional) Either an observer with methods to be called,
  190. * or the first of three possible handlers, which is the handler for each value emitted from the subscribed
  191. * Observable.
  192. * @param {Function} error (optional) A handler for a terminal event resulting from an error. If no error handler is provided,
  193. * the error will be thrown as unhandled.
  194. * @param {Function} complete (optional) A handler for a terminal event resulting from successful completion.
  195. * @return {ISubscription} a subscription reference to the registered handlers
  196. * @method subscribe
  197. */
  198. subscribe(observerOrNext?: PartialObserver<T> | ((value: T) => void),
  199. error?: (error: any) => void,
  200. complete?: () => void): Subscription {
  201. const { operator } = this;
  202. const sink = toSubscriber(observerOrNext, error, complete);
  203. if (operator) {
  204. sink.add(operator.call(sink, this.source));
  205. } else {
  206. sink.add(
  207. this.source || (config.useDeprecatedSynchronousErrorHandling && !sink.syncErrorThrowable) ?
  208. this._subscribe(sink) :
  209. this._trySubscribe(sink)
  210. );
  211. }
  212. if (config.useDeprecatedSynchronousErrorHandling) {
  213. if (sink.syncErrorThrowable) {
  214. sink.syncErrorThrowable = false;
  215. if (sink.syncErrorThrown) {
  216. throw sink.syncErrorValue;
  217. }
  218. }
  219. }
  220. return sink;
  221. }
  222. /** @deprecated This is an internal implementation detail, do not use. */
  223. _trySubscribe(sink: Subscriber<T>): TeardownLogic {
  224. try {
  225. return this._subscribe(sink);
  226. } catch (err) {
  227. if (config.useDeprecatedSynchronousErrorHandling) {
  228. sink.syncErrorThrown = true;
  229. sink.syncErrorValue = err;
  230. }
  231. if (canReportError(sink)) {
  232. sink.error(err);
  233. } else {
  234. console.warn(err);
  235. }
  236. }
  237. }
  238. /**
  239. * @method forEach
  240. * @param {Function} next a handler for each value emitted by the observable
  241. * @param {PromiseConstructor} [promiseCtor] a constructor function used to instantiate the Promise
  242. * @return {Promise} a promise that either resolves on observable completion or
  243. * rejects with the handled error
  244. */
  245. forEach(next: (value: T) => void, promiseCtor?: PromiseConstructorLike): Promise<void> {
  246. promiseCtor = getPromiseCtor(promiseCtor);
  247. return new promiseCtor<void>((resolve, reject) => {
  248. // Must be declared in a separate statement to avoid a ReferenceError when
  249. // accessing subscription below in the closure due to Temporal Dead Zone.
  250. let subscription: Subscription;
  251. subscription = this.subscribe((value) => {
  252. try {
  253. next(value);
  254. } catch (err) {
  255. reject(err);
  256. if (subscription) {
  257. subscription.unsubscribe();
  258. }
  259. }
  260. }, reject, resolve);
  261. }) as Promise<void>;
  262. }
  263. /** @internal This is an internal implementation detail, do not use. */
  264. _subscribe(subscriber: Subscriber<any>): TeardownLogic {
  265. const { source } = this;
  266. return source && source.subscribe(subscriber);
  267. }
  268. // `if` and `throw` are special snow flakes, the compiler sees them as reserved words. Deprecated in
  269. // favor of iif and throwError functions.
  270. /**
  271. * @nocollapse
  272. * @deprecated In favor of iif creation function: import { iif } from 'rxjs';
  273. */
  274. static if: typeof iif;
  275. /**
  276. * @nocollapse
  277. * @deprecated In favor of throwError creation function: import { throwError } from 'rxjs';
  278. */
  279. static throw: typeof throwError;
  280. /**
  281. * An interop point defined by the es7-observable spec https://github.com/zenparsing/es-observable
  282. * @method Symbol.observable
  283. * @return {Observable} this instance of the observable
  284. */
  285. [Symbol_observable]() {
  286. return this;
  287. }
  288. /* tslint:disable:max-line-length */
  289. pipe(): Observable<T>;
  290. pipe<A>(op1: OperatorFunction<T, A>): Observable<A>;
  291. pipe<A, B>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>): Observable<B>;
  292. pipe<A, B, C>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>): Observable<C>;
  293. pipe<A, B, C, D>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>, op4: OperatorFunction<C, D>): Observable<D>;
  294. pipe<A, B, C, D, E>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>, op4: OperatorFunction<C, D>, op5: OperatorFunction<D, E>): Observable<E>;
  295. pipe<A, B, C, D, E, F>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>, op4: OperatorFunction<C, D>, op5: OperatorFunction<D, E>, op6: OperatorFunction<E, F>): Observable<F>;
  296. pipe<A, B, C, D, E, F, G>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>, op4: OperatorFunction<C, D>, op5: OperatorFunction<D, E>, op6: OperatorFunction<E, F>, op7: OperatorFunction<F, G>): Observable<G>;
  297. pipe<A, B, C, D, E, F, G, H>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>, op4: OperatorFunction<C, D>, op5: OperatorFunction<D, E>, op6: OperatorFunction<E, F>, op7: OperatorFunction<F, G>, op8: OperatorFunction<G, H>): Observable<H>;
  298. pipe<A, B, C, D, E, F, G, H, I>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>, op4: OperatorFunction<C, D>, op5: OperatorFunction<D, E>, op6: OperatorFunction<E, F>, op7: OperatorFunction<F, G>, op8: OperatorFunction<G, H>, op9: OperatorFunction<H, I>): Observable<I>;
  299. pipe<A, B, C, D, E, F, G, H, I>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>, op4: OperatorFunction<C, D>, op5: OperatorFunction<D, E>, op6: OperatorFunction<E, F>, op7: OperatorFunction<F, G>, op8: OperatorFunction<G, H>, op9: OperatorFunction<H, I>, ...operations: OperatorFunction<any, any>[]): Observable<{}>;
  300. /* tslint:enable:max-line-length */
  301. /**
  302. * Used to stitch together functional operators into a chain.
  303. * @method pipe
  304. * @return {Observable} the Observable result of all of the operators having
  305. * been called in the order they were passed in.
  306. *
  307. * ### Example
  308. * ```ts
  309. * import { interval } from 'rxjs';
  310. * import { map, filter, scan } from 'rxjs/operators';
  311. *
  312. * interval(1000)
  313. * .pipe(
  314. * filter(x => x % 2 === 0),
  315. * map(x => x + x),
  316. * scan((acc, x) => acc + x)
  317. * )
  318. * .subscribe(x => console.log(x))
  319. * ```
  320. */
  321. pipe(...operations: OperatorFunction<any, any>[]): Observable<any> {
  322. if (operations.length === 0) {
  323. return this as any;
  324. }
  325. return pipeFromArray(operations)(this);
  326. }
  327. /* tslint:disable:max-line-length */
  328. toPromise<T>(this: Observable<T>): Promise<T>;
  329. toPromise<T>(this: Observable<T>, PromiseCtor: typeof Promise): Promise<T>;
  330. toPromise<T>(this: Observable<T>, PromiseCtor: PromiseConstructorLike): Promise<T>;
  331. /* tslint:enable:max-line-length */
  332. toPromise(promiseCtor?: PromiseConstructorLike): Promise<T> {
  333. promiseCtor = getPromiseCtor(promiseCtor);
  334. return new promiseCtor((resolve, reject) => {
  335. let value: any;
  336. this.subscribe((x: T) => value = x, (err: any) => reject(err), () => resolve(value));
  337. }) as Promise<T>;
  338. }
  339. }
  340. /**
  341. * Decides between a passed promise constructor from consuming code,
  342. * A default configured promise constructor, and the native promise
  343. * constructor and returns it. If nothing can be found, it will throw
  344. * an error.
  345. * @param promiseCtor The optional promise constructor to passed by consuming code
  346. */
  347. function getPromiseCtor(promiseCtor: PromiseConstructorLike | undefined) {
  348. if (!promiseCtor) {
  349. promiseCtor = config.Promise || Promise;
  350. }
  351. if (!promiseCtor) {
  352. throw new Error('no Promise impl found');
  353. }
  354. return promiseCtor;
  355. }