SHARE
TWEET

Untitled

a guest Oct 21st, 2019 64 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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);
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top