ZipWithLatestForm *需要操作员*或解决方法
ZipWithLatestForm *Wanted Operator* or Workaround
让我们考虑以下流:
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()
and/or withLatestForm()
,但我想不出解决方案
- 主要想法是我有 500 毫秒的间隔,并且在每次滴答时我想用 Keyboard Input Observable 压缩它,这按我想要的方式工作,但只要我不发出 Keyboard Input Observable一切都停止了。 我想继续发出间隔滴答声,但如果键盘事件停止,则取最新值
你可以只使用 withLatestFrom
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
一旦您聚焦页面并按下某个键,流就会开始,您将在每次滴答时获得一个发射值,无论您自上次滴答后是否单击了按钮。
我对 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);
经过一段时间的思考,我想出了这样的解决方案,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 的帮助下延迟了 input$(注意 take(1))。
ConcatMap 帮助我延长了 input$ 事件并等待间隔事件触发它自己的事件。使用 withLatestForm 帮助我将刻度与其自己的 input$ 值相匹配。
让我们考虑以下流:
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()
and/or withLatestForm()
,但我想不出解决方案
- 主要想法是我有 500 毫秒的间隔,并且在每次滴答时我想用 Keyboard Input Observable 压缩它,这按我想要的方式工作,但只要我不发出 Keyboard Input Observable一切都停止了。 我想继续发出间隔滴答声,但如果键盘事件停止,则取最新值
你可以只使用 withLatestFrom
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
一旦您聚焦页面并按下某个键,流就会开始,您将在每次滴答时获得一个发射值,无论您自上次滴答后是否单击了按钮。
我对 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);
经过一段时间的思考,我想出了这样的解决方案,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 的帮助下延迟了 input$(注意 take(1))。
ConcatMap 帮助我延长了 input$ 事件并等待间隔事件触发它自己的事件。使用 withLatestForm 帮助我将刻度与其自己的 input$ 值相匹配。