Advertisement
Guest User

Untitled

a guest
Oct 21st, 2019
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.78 KB | None | 0 0
  1. const logger = {
  2. next(value) {
  3. console.log(value);
  4. }
  5. };
  6. const logger2 = {
  7. next(value) {
  8. console.log("logger 2 " + value);
  9. }
  10. };
  11.  
  12. class Observable {
  13. constructor(subscriberOps) {
  14. this.subscriptions = [];
  15. this.subscriberOps = subscriber => {
  16. if (!this.subscriptions.find(s => s.subscriber === subscriber)) {
  17. return;
  18. }
  19. subscriberOps(subscriber);
  20. };
  21.  
  22. this.pipePlugins = [];
  23. }
  24.  
  25. patchSubscriber(subscriber) {
  26. if (!subscriber.next) {
  27. return;
  28. }
  29.  
  30. let decoratedSubscriber = subscriber;
  31. for (const plugin of this.pipePlugins) {
  32. decoratedSubscriber = plugin(decoratedSubscriber);
  33. }
  34.  
  35. this.subscriptions.push({
  36. originSubscriber: subscriber,
  37. subscriber: decoratedSubscriber
  38. });
  39.  
  40. return decoratedSubscriber;
  41. }
  42.  
  43. dispatchSubscriber(subscriber) {
  44. if (!subscriber.next) {
  45. return;
  46. }
  47.  
  48. this.subscriptions = this.subscriptions.filter(
  49. s => s.originSubscriber !== subscriber
  50. );
  51. }
  52.  
  53. subscribe(subscriber) {
  54. let observableSubscriber = this.subscriptions.find(
  55. s => s.originSubscriber === subscriber
  56. );
  57. observableSubscriber =
  58. observableSubscriber && observableSubscriber.subscriber;
  59. if (!observableSubscriber) {
  60. observableSubscriber = this.patchSubscriber(subscriber);
  61. }
  62. this.subscriberOps(observableSubscriber);
  63.  
  64. return this.unsubscriber(subscriber);
  65. }
  66.  
  67. unsubscriber = subscriber => {
  68. return () => {
  69. if (this.subscriptions.find(s => s.originSubscriber === subscriber)) {
  70. this.dispatchSubscriber(subscriber);
  71. }
  72. };
  73. };
  74.  
  75. unsubscribe = subscriber => {
  76. if (this.subscriptions.find(s => s.originSubscriber === subscriber)) {
  77. this.dispatchSubscriber(subscriber);
  78. }
  79. };
  80.  
  81. pipe(...decorators) {
  82. for (const decorator of decorators) {
  83. this.pipePlugins.unshift(decorator);
  84. }
  85. return this;
  86. }
  87. }
  88.  
  89. class Subject extends Observable {
  90. constructor() {
  91. super(subscriber => {
  92. if (!this.nextValue) {
  93. return;
  94. }
  95.  
  96. subscriber.next(this.nextValue);
  97. });
  98.  
  99. this.nextValue = undefined;
  100. }
  101.  
  102. subscribe(subscriber) {
  103. let observableSubscriber = this.subscriptions.find(
  104. s => s.originSubscriber === subscriber
  105. );
  106. observableSubscriber =
  107. observableSubscriber && observableSubscriber.subscriber;
  108. if (!observableSubscriber) {
  109. observableSubscriber = this.patchSubscriber(subscriber);
  110. }
  111.  
  112. return this.unsubscriber(subscriber);
  113. }
  114.  
  115. next(value) {
  116. this.nextValue = value;
  117. for (const subscriber of this.subscriptions) {
  118. this.subscriberOps(subscriber.subscriber);
  119. }
  120. }
  121. }
  122.  
  123. function echo() {
  124. return subscriber => ({
  125. next: value => {
  126. subscriber.next(value);
  127. subscriber.next(value);
  128. }
  129. });
  130. }
  131.  
  132. function distinct() {
  133. const distinctValues = [];
  134. return subscriber => ({
  135. next: value => {
  136. if (distinctValues.includes(value)) {
  137. return;
  138. } else {
  139. distinctValues.push(value);
  140. subscriber.next(value);
  141. }
  142. }
  143. });
  144. }
  145.  
  146. function map(mapRule) {
  147. return subscriber => ({
  148. next: value => {
  149. subscriber.next(mapRule(value));
  150. }
  151. });
  152. }
  153.  
  154. function debounce(time) {
  155. return subscriber => ({
  156. next: value => {
  157. setTimeout(() => {
  158. subscriber.next(value);
  159. }, time);
  160. }
  161. });
  162. }
  163.  
  164. function throttle(time) {
  165. let timeout;
  166. let stopped = true;
  167. let lastRunningValue;
  168. let currentValue;
  169.  
  170. const stop = callback => setTimeout(callback, 10);
  171.  
  172. return subscriber => ({
  173. next: value => {
  174. currentValue = value;
  175. if (timeout) {
  176. return;
  177. }
  178.  
  179. if (stopped) {
  180. subscriber.next(currentValue);
  181. lastRunningValue = currentValue;
  182. stopped = false;
  183. return;
  184. }
  185.  
  186. checkStop = true;
  187. timeout = setTimeout(() => {
  188. clearTimeout(timeout);
  189. timeout = undefined;
  190. lastRunningValue = currentValue;
  191. stop(() => {
  192. stopped = lastRunningValue === currentValue;
  193. subscriber.next(lastRunningValue);
  194. });
  195. }, time);
  196. }
  197. });
  198. }
  199.  
  200. const o = new Observable(subscriber => {
  201. let count = 0;
  202. const display = document.getElementById("display");
  203. document.addEventListener("mousemove", () => {
  204. count++;
  205. display.innerText = count;
  206. subscriber.next(count);
  207. });
  208. });
  209.  
  210. o.pipe(
  211. debounce(1000),
  212. throttle(1000),
  213. map(value => `throttle: ${value}`)
  214. ).subscribe(logger);
  215.  
  216. const s1 = new Subject();
  217. s1.next("never");
  218. s1.subscribe(logger);
  219. s1.subscribe(logger2);
  220. s1.next("hello world");
  221. s1.unsubscribe(logger);
  222. s1.next("hello world 2");
  223. s1.subscribe(logger);
  224. s1.next("hello world 3");
  225.  
  226. new Observable(subscriber => {
  227. [1, 2, 3, 4, 4, 3, 2, 1, 5].map(value => subscriber.next(value));
  228. })
  229. .pipe(
  230. debounce(1000),
  231. distinct(),
  232. map(value => value * value),
  233. echo()
  234. )
  235. .subscribe(logger);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement