PageRenderTime 49ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/ajax/libs/rxjs/2.3.20/rx.backpressure.js

https://gitlab.com/Mirros/cdnjs
JavaScript | 424 lines | 328 code | 62 blank | 34 comment | 74 complexity | c9e5a2dae83983d8e5ac6050e70c3e50 MD5 | raw file
  1. // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
  2. ;(function (factory) {
  3. var objectTypes = {
  4. 'boolean': false,
  5. 'function': true,
  6. 'object': true,
  7. 'number': false,
  8. 'string': false,
  9. 'undefined': false
  10. };
  11. var root = (objectTypes[typeof window] && window) || this,
  12. freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports,
  13. freeModule = objectTypes[typeof module] && module && !module.nodeType && module,
  14. moduleExports = freeModule && freeModule.exports === freeExports && freeExports,
  15. freeGlobal = objectTypes[typeof global] && global;
  16. if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
  17. root = freeGlobal;
  18. }
  19. // Because of build optimizers
  20. if (typeof define === 'function' && define.amd) {
  21. define(['rx'], function (Rx, exports) {
  22. return factory(root, exports, Rx);
  23. });
  24. } else if (typeof module === 'object' && module && module.exports === freeExports) {
  25. module.exports = factory(root, module.exports, require('./rx'));
  26. } else {
  27. root.Rx = factory(root, {}, root.Rx);
  28. }
  29. }.call(this, function (root, exp, Rx, undefined) {
  30. // References
  31. var Observable = Rx.Observable,
  32. observableProto = Observable.prototype,
  33. AnonymousObservable = Rx.AnonymousObservable,
  34. CompositeDisposable = Rx.CompositeDisposable,
  35. Subject = Rx.Subject,
  36. Observer = Rx.Observer,
  37. disposableEmpty = Rx.Disposable.empty,
  38. disposableCreate = Rx.Disposable.create,
  39. inherits = Rx.internals.inherits,
  40. addProperties = Rx.internals.addProperties,
  41. timeoutScheduler = Rx.Scheduler.timeout,
  42. identity = Rx.helpers.identity;
  43. var objectDisposed = 'Object has been disposed';
  44. function checkDisposed() { if (this.isDisposed) { throw new Error(objectDisposed); } }
  45. var PausableObservable = (function (_super) {
  46. inherits(PausableObservable, _super);
  47. function subscribe(observer) {
  48. var conn = this.source.publish(),
  49. subscription = conn.subscribe(observer),
  50. connection = disposableEmpty;
  51. var pausable = this.pauser.distinctUntilChanged().subscribe(function (b) {
  52. if (b) {
  53. connection = conn.connect();
  54. } else {
  55. connection.dispose();
  56. connection = disposableEmpty;
  57. }
  58. });
  59. return new CompositeDisposable(subscription, connection, pausable);
  60. }
  61. function PausableObservable(source, pauser) {
  62. this.source = source;
  63. this.controller = new Subject();
  64. if (pauser && pauser.subscribe) {
  65. this.pauser = this.controller.merge(pauser);
  66. } else {
  67. this.pauser = this.controller;
  68. }
  69. _super.call(this, subscribe);
  70. }
  71. PausableObservable.prototype.pause = function () {
  72. this.controller.onNext(false);
  73. };
  74. PausableObservable.prototype.resume = function () {
  75. this.controller.onNext(true);
  76. };
  77. return PausableObservable;
  78. }(Observable));
  79. /**
  80. * Pauses the underlying observable sequence based upon the observable sequence which yields true/false.
  81. * @example
  82. * var pauser = new Rx.Subject();
  83. * var source = Rx.Observable.interval(100).pausable(pauser);
  84. * @param {Observable} pauser The observable sequence used to pause the underlying sequence.
  85. * @returns {Observable} The observable sequence which is paused based upon the pauser.
  86. */
  87. observableProto.pausable = function (pauser) {
  88. return new PausableObservable(this, pauser);
  89. };
  90. function combineLatestSource(source, subject, resultSelector) {
  91. return new AnonymousObservable(function (observer) {
  92. var hasValue = [false, false],
  93. hasValueAll = false,
  94. isDone = false,
  95. values = new Array(2),
  96. err;
  97. function next(x, i) {
  98. values[i] = x
  99. var res;
  100. hasValue[i] = true;
  101. if (hasValueAll || (hasValueAll = hasValue.every(identity))) {
  102. if (err) {
  103. observer.onError(err);
  104. return;
  105. }
  106. try {
  107. res = resultSelector.apply(null, values);
  108. } catch (ex) {
  109. observer.onError(ex);
  110. return;
  111. }
  112. observer.onNext(res);
  113. }
  114. if (isDone && values[1]) {
  115. observer.onCompleted();
  116. }
  117. }
  118. return new CompositeDisposable(
  119. source.subscribe(
  120. function (x) {
  121. next(x, 0);
  122. },
  123. function (e) {
  124. if (values[1]) {
  125. observer.onError(e);
  126. } else {
  127. err = e;
  128. }
  129. },
  130. function () {
  131. isDone = true;
  132. values[1] && observer.onCompleted();
  133. }),
  134. subject.subscribe(
  135. function (x) {
  136. next(x, 1);
  137. },
  138. observer.onError.bind(observer),
  139. function () {
  140. isDone = true;
  141. next(true, 1);
  142. })
  143. );
  144. });
  145. }
  146. var PausableBufferedObservable = (function (__super__) {
  147. inherits(PausableBufferedObservable, __super__);
  148. function subscribe(observer) {
  149. var q = [], previousShouldFire;
  150. var subscription =
  151. combineLatestSource(
  152. this.source,
  153. this.pauser.distinctUntilChanged().startWith(false),
  154. function (data, shouldFire) {
  155. return { data: data, shouldFire: shouldFire };
  156. })
  157. .subscribe(
  158. function (results) {
  159. if (previousShouldFire !== undefined && results.shouldFire != previousShouldFire) {
  160. previousShouldFire = results.shouldFire;
  161. // change in shouldFire
  162. if (results.shouldFire) {
  163. while (q.length > 0) {
  164. observer.onNext(q.shift());
  165. }
  166. }
  167. } else {
  168. previousShouldFire = results.shouldFire;
  169. // new data
  170. if (results.shouldFire) {
  171. observer.onNext(results.data);
  172. } else {
  173. q.push(results.data);
  174. }
  175. }
  176. },
  177. function (err) {
  178. // Empty buffer before sending error
  179. while (q.length > 0) {
  180. observer.onNext(q.shift());
  181. }
  182. observer.onError(err);
  183. },
  184. function () {
  185. // Empty buffer before sending completion
  186. while (q.length > 0) {
  187. observer.onNext(q.shift());
  188. }
  189. observer.onCompleted();
  190. }
  191. );
  192. return subscription;
  193. }
  194. function PausableBufferedObservable(source, pauser) {
  195. this.source = source;
  196. this.controller = new Subject();
  197. if (pauser && pauser.subscribe) {
  198. this.pauser = this.controller.merge(pauser);
  199. } else {
  200. this.pauser = this.controller;
  201. }
  202. __super__.call(this, subscribe);
  203. }
  204. PausableBufferedObservable.prototype.pause = function () {
  205. this.controller.onNext(false);
  206. };
  207. PausableBufferedObservable.prototype.resume = function () {
  208. this.controller.onNext(true);
  209. };
  210. return PausableBufferedObservable;
  211. }(Observable));
  212. /**
  213. * Pauses the underlying observable sequence based upon the observable sequence which yields true/false,
  214. * and yields the values that were buffered while paused.
  215. * @example
  216. * var pauser = new Rx.Subject();
  217. * var source = Rx.Observable.interval(100).pausableBuffered(pauser);
  218. * @param {Observable} pauser The observable sequence used to pause the underlying sequence.
  219. * @returns {Observable} The observable sequence which is paused based upon the pauser.
  220. */
  221. observableProto.pausableBuffered = function (subject) {
  222. return new PausableBufferedObservable(this, subject);
  223. };
  224. /**
  225. * Attaches a controller to the observable sequence with the ability to queue.
  226. * @example
  227. * var source = Rx.Observable.interval(100).controlled();
  228. * source.request(3); // Reads 3 values
  229. * @param {Observable} pauser The observable sequence used to pause the underlying sequence.
  230. * @returns {Observable} The observable sequence which is paused based upon the pauser.
  231. */
  232. observableProto.controlled = function (enableQueue) {
  233. if (enableQueue == null) { enableQueue = true; }
  234. return new ControlledObservable(this, enableQueue);
  235. };
  236. var ControlledObservable = (function (_super) {
  237. inherits(ControlledObservable, _super);
  238. function subscribe (observer) {
  239. return this.source.subscribe(observer);
  240. }
  241. function ControlledObservable (source, enableQueue) {
  242. _super.call(this, subscribe);
  243. this.subject = new ControlledSubject(enableQueue);
  244. this.source = source.multicast(this.subject).refCount();
  245. }
  246. ControlledObservable.prototype.request = function (numberOfItems) {
  247. if (numberOfItems == null) { numberOfItems = -1; }
  248. return this.subject.request(numberOfItems);
  249. };
  250. return ControlledObservable;
  251. }(Observable));
  252. var ControlledSubject = Rx.ControlledSubject = (function (_super) {
  253. function subscribe (observer) {
  254. return this.subject.subscribe(observer);
  255. }
  256. inherits(ControlledSubject, _super);
  257. function ControlledSubject(enableQueue) {
  258. if (enableQueue == null) {
  259. enableQueue = true;
  260. }
  261. _super.call(this, subscribe);
  262. this.subject = new Subject();
  263. this.enableQueue = enableQueue;
  264. this.queue = enableQueue ? [] : null;
  265. this.requestedCount = 0;
  266. this.requestedDisposable = disposableEmpty;
  267. this.error = null;
  268. this.hasFailed = false;
  269. this.hasCompleted = false;
  270. this.controlledDisposable = disposableEmpty;
  271. }
  272. addProperties(ControlledSubject.prototype, Observer, {
  273. onCompleted: function () {
  274. checkDisposed.call(this);
  275. this.hasCompleted = true;
  276. if (!this.enableQueue || this.queue.length === 0) {
  277. this.subject.onCompleted();
  278. }
  279. },
  280. onError: function (error) {
  281. checkDisposed.call(this);
  282. this.hasFailed = true;
  283. this.error = error;
  284. if (!this.enableQueue || this.queue.length === 0) {
  285. this.subject.onError(error);
  286. }
  287. },
  288. onNext: function (value) {
  289. checkDisposed.call(this);
  290. var hasRequested = false;
  291. if (this.requestedCount === 0) {
  292. if (this.enableQueue) {
  293. this.queue.push(value);
  294. }
  295. } else {
  296. if (this.requestedCount !== -1) {
  297. if (this.requestedCount-- === 0) {
  298. this.disposeCurrentRequest();
  299. }
  300. }
  301. hasRequested = true;
  302. }
  303. if (hasRequested) {
  304. this.subject.onNext(value);
  305. }
  306. },
  307. _processRequest: function (numberOfItems) {
  308. if (this.enableQueue) {
  309. //console.log('queue length', this.queue.length);
  310. while (this.queue.length >= numberOfItems && numberOfItems > 0) {
  311. //console.log('number of items', numberOfItems);
  312. this.subject.onNext(this.queue.shift());
  313. numberOfItems--;
  314. }
  315. if (this.queue.length !== 0) {
  316. return { numberOfItems: numberOfItems, returnValue: true };
  317. } else {
  318. return { numberOfItems: numberOfItems, returnValue: false };
  319. }
  320. }
  321. if (this.hasFailed) {
  322. this.subject.onError(this.error);
  323. this.controlledDisposable.dispose();
  324. this.controlledDisposable = disposableEmpty;
  325. } else if (this.hasCompleted) {
  326. this.subject.onCompleted();
  327. this.controlledDisposable.dispose();
  328. this.controlledDisposable = disposableEmpty;
  329. }
  330. return { numberOfItems: numberOfItems, returnValue: false };
  331. },
  332. request: function (number) {
  333. checkDisposed.call(this);
  334. this.disposeCurrentRequest();
  335. var self = this,
  336. r = this._processRequest(number);
  337. number = r.numberOfItems;
  338. if (!r.returnValue) {
  339. this.requestedCount = number;
  340. this.requestedDisposable = disposableCreate(function () {
  341. self.requestedCount = 0;
  342. });
  343. return this.requestedDisposable
  344. } else {
  345. return disposableEmpty;
  346. }
  347. },
  348. disposeCurrentRequest: function () {
  349. this.requestedDisposable.dispose();
  350. this.requestedDisposable = disposableEmpty;
  351. },
  352. dispose: function () {
  353. this.isDisposed = true;
  354. this.error = null;
  355. this.subject.dispose();
  356. this.requestedDisposable.dispose();
  357. }
  358. });
  359. return ControlledSubject;
  360. }(Observable));
  361. return Rx;
  362. }));