代码之家  ›  专栏  ›  技术社区  ›  Goga Koreli

ZipWithLatestForm*所需操作员*或解决方案

  •  0
  • Goga Koreli  · 技术社区  · 6 年前

    让我们考虑以下流:

    Stream1: 1  2  3  4  5  6  7  8  9                
    Stream2: abc  d       fg   h
    

    我想结合这些流得到的输出:

    [1, a]
    [2, b]
    [3, c]
    [4, d]
    [5, d]
    [6, f]
    [7, g]
    [8, h]
    [9, h]
    

    示例代码思想: StackBlitz Editor Link

    const input$ = fromEvent(document, 'keydown')
      .pipe(
        map((event: KeyboardEvent) => event.keyCode)
      );
    const source$ = interval(500).pipe(s$ => zip(s$, input$))
    source$.subscribe(x => console.log(x));
    

    这有点像运算符 zip() 和/或 withLatestForm() 但是我想不出解决办法

    • 主要的想法是,我有500毫秒的间隔,在每一个勾号上,我想用键盘输入observable压缩它,这是我想要的工作方式,但只要我不发出键盘输入observable,一切都会停止。 我想继续发出间隔信号,但如果键盘事件停止,则取最新值
    3 回复  |  直到 6 年前
        1
  •  0
  •   Bene    6 年前

    您可以在最晚使用

    import { of, fromEvent, interval } from 'rxjs'; 
    import { map, withLatestFrom } from 'rxjs/operators';
    
    const input$ = fromEvent(document, 'keydown').pipe( map((event: KeyboardEvent) => event.keyCode));
    const timer$ = interval(1000);
    const source$ = timer$.pipe(withLatestFrom(input$));
    
    source$.subscribe(x => console.log(x));
    

    在StackBlitz上试用此实况演示-> https://stackblitz.com/edit/rxjs-bmx7hg

    只要您聚焦页面并按下某个键,流就会启动,并且您将在每个刻度上获得一个发射值,无论您是否单击了上一个刻度之后的按钮。

        2
  •  0
  •   Bergi    6 年前

    我不太了解RXJS,不能说是否有一个内置组件已经做到了这一点,但是您应该能够用一个显式队列来处理它:

    import { of, fromEvent, interval } from 'rxjs'; 
    import { map, withLatestFrom } from 'rxjs/operators';
    
    const queue = [];
    const input$ = fromEvent(document, 'keydown').pipe(map((event: KeyboardEvent) => {
        queue.push(event.keyCode);
        return queue;
    });
    const timer$ = interval(1000);
    const source$ = timer$.pipe(withLatestFrom(input$), map(([tick, queue]) => {
        if (queue.length > 1)
            return queue.shift();
        else
            return queue[0];
    }));
    
    source$.subscribe(console.log);
    
        3
  •  0
  •   Goga Koreli    6 年前

    经过一段时间的思考,我想出了这样的解决方案, StackBlitz Edit Link :

    const interval$ = interval(500).pipe(share());
    const input$ = fromEvent(document, 'keydown')
      .pipe(
        map((event: KeyboardEvent) => event.keyCode),
        concatMap(key => interval$.pipe(map(tick => key), take(1))),
      );
    
    const source$ = interval$.pipe(withLatestFrom(input$))
    source$.subscribe(x => console.log(x));
    

    我在interval$和concatmap(注意事项(1))的帮助下延迟了input$的输入。

    concatmap帮助我延长input$events并等待interval事件触发它自己的事件。使用withlatestform帮助我将tick与它们自己的输入$values匹配起来。