zoukankan      html  css  js  c++  java
  • [RxJS] SwitchAll()

    Converts a higher-order Observable into a first-order Observable producing values only from the most recent observable sequence

    switchAll marble diagram

    import './style.css';
    
    import { fromEvent, of, merge, empty, concat, defer } from 'rxjs';
    import {
      delay,
      map,
      mergeMap,
      tap,
      debounceTime,
      distinctUntilChanged,
      mapTo,
      filter,
      share,
      switchAll
    } from 'rxjs/operators';
    import { format } from 'date-fns';
    
    // track in progress saves
    let savesInProgress = 0;
    
    // references
    const input = document.getElementById('note-input');
    const saveIndicator = document.querySelector('.save-indicator');
    
    // streams
    const keyup$ = fromEvent(input, 'keyup');
    
    // fake save request
    const saveChanges = value => {
      return of(value).pipe(delay(1500));
    };
    
    /**
     * Trigger a save when the user stops typing for 200ms
     * After new data has been successfully saved, so a saved
     * and last updated indicator.
     */
    const inputToSave$ = keyup$.pipe(
      debounceTime(200),
      // @ts-ignore
      map(e => e.target.value),
      distinctUntilChanged(),
      share()
    );
    
    const savesInProgress$ = inputToSave$.pipe(
      mapTo(of('Saving')),
      tap(_ => {
        savesInProgress++;
        console.log('savesInProgress++', savesInProgress);
      })
    );
    
    const savesCompleted$ = inputToSave$.pipe(
      mergeMap(saveChanges),
      tap(_ => {
        savesInProgress--;
        console.log('savesInProgress++', savesInProgress);
      }),
      // ignore if additional saves are in progress
      filter(_ => !savesInProgress),
      mapTo(
        concat(
          // display saved for 2s
          of('Saved!'),
          empty().pipe(delay(2000)),
          // then last updated time, defer for proper time
          defer(() =>
            of(`Last updated: ${format(Date.now(), 'MM/DD/YYYY hh:mm:ss')}`)
          )
        )
      )
    );
    
    merge(savesInProgress$, savesCompleted$)
      .pipe(
        /*
       If new save comes in when our completion observable is running, we want to switch to it for a status update.
      */
        switchAll()
      )
      .subscribe(status => {
        saveIndicator.innerHTML = status;
      });

  • 相关阅读:
    CSS+JS实现兼容性很好的无限级下拉菜单
    自动切换的JS菜单
    (2)C#连sqlite
    protobuf编译器
    (67) c# 序列化
    (66) c# async await
    (65)C# 任务
    mbatis 入门
    (64)C# 预处理器指令
    (63)C# 不安全代码unsafe
  • 原文地址:https://www.cnblogs.com/Answer1215/p/15291619.html
Copyright © 2011-2022 走看看