• [RxJS] Refactoring Composable Streams in RxJS, switchMap()


    Refactoring streams in RxJS is mostly moving pieces of smaller streams around. This lessons demonstrates a simple refactoring by requiring the StopWatch to be more configurable.

     Code we have now:
    const Observable = Rx.Observable;
    
    const startButton = document.querySelector('#start');
    const stopButton = document.querySelector('#stop');
    const resetButton = document.querySelector('#reset');
    
    const start$ = Observable.fromEvent(startButton, 'click');
    const interval$ = Observable.interval(1000);
    const stop$ = Observable.fromEvent(stopButton, 'click');
    const reset$ = Observable.fromEvent(resetButton, 'click');
    
    
    const data = {count:0};
    const inc = (acc)=> ({count: acc.count + 1});
    const reset = (acc)=> data;
    
    const intervalThatStops$ = interval$
        .takeUntil(stop$);
    
    const incOrReset$ = Observable.merge(
        intervalThatStops$.mapTo(inc),
        reset$.mapTo(reset)
    );
    
    start$
        .switchMapTo(incOrReset$)
        .startWith(data)
        .scan((acc, curr)=> curr(acc))
        .subscribe((x)=> console.log(x));

    Currently the interval is hard code 1000, we want it more flexable:

    const Observable = Rx.Observable;
    
    const startButton = document.querySelector('#start');
    const halfButton = document.querySelector('#half');
    const quarterButton = document.querySelector('#quarter');
    
    const stopButton = document.querySelector('#stop');
    const resetButton = document.querySelector('#reset');
    
    const start$ = Observable.fromEvent(startButton, 'click');
    const half$ = Observable.fromEvent(halfButton, 'click');
    const quarter$ = Observable.fromEvent(quarterButton, 'click');
    
    const stop$ = Observable.fromEvent(stopButton, 'click');
    const reset$ = Observable.fromEvent(resetButton, 'click');

    We added two more buttons, halfButton set interval as 500, and quarterButton is 250.

    So when we click "start", "half" or "quarter" button, the interval will set differently.

     Observable.merge(
        start$.mapTo(1000),
        half$.mapTo(500),
        quarter$.mapTo(250)
     )

    We want pass the time (1000, 500, 250) to the next observable to control the time.

     Observable.merge(
        start$.mapTo(1000),
        half$.mapTo(500),
        quarter$.mapTo(250)
     )
      .switchMap(
        (time) => {
          return Observable.merge(
            Observable.interval(time)
            .takeUntil(stop$)
            .mapTo(inc),
            reset$.mapTo(reset)
          )
        }
      )

    We use switchMap() instead of switchMapTo() is becuase switchMapTo() accept observable as param and switchMap accpet a function which return an Observable. So use switchMap() is more flexable.

    -------------

    const Observable = Rx.Observable;
    
    const startButton = document.querySelector('#start');
    const halfButton = document.querySelector('#half');
    const quarterButton = document.querySelector('#quarter');
    
    const stopButton = document.querySelector('#stop');
    const resetButton = document.querySelector('#reset');
    
    const start$ = Observable.fromEvent(startButton, 'click');
    const half$ = Observable.fromEvent(halfButton, 'click');
    const quarter$ = Observable.fromEvent(quarterButton, 'click');
    
    const stop$ = Observable.fromEvent(stopButton, 'click');
    const reset$ = Observable.fromEvent(resetButton, 'click');
    
    
    const data = {count:0};
    const inc = (acc)=> ({count: acc.count + 1});
    const reset = (acc)=> data;
    
     Observable.merge(
        start$.mapTo(1000),
        half$.mapTo(500),
        quarter$.mapTo(250)
     )
      .switchMap(
        (time) => {
          return Observable.merge(
            Observable.interval(time)
            .takeUntil(stop$)
            .mapTo(inc),
            reset$.mapTo(reset)
          )
        }
      )
     .startWith(data)
     .scan( (acc, curr) => curr(acc))
     .subscribe( (z) => console.log(z) );
  • 相关阅读:
    Contiki学习笔记  第一个程序:Hello World
    contiki学习笔记---process结构体
    MYSQL碰到The total number of locks exceeds the lock table size 问题解决记录
    navicat连接mysql查询结果中文都是?号(C#)
    C#使用OracleBulkCopy
    解决IIS应用程序池默认回收导致程序崩溃
    构建可读性更高的 ASP.NET Core 路由机制
    .Net(C#)汉字和Unicode编码互相转换
    聊聊c#字符串拼接
    VS2010到VS2019各个版本的密钥
  • 原文地址:https://www.cnblogs.com/Answer1215/p/5264164.html
Copyright © 2020-2023  润新知