RxJS:可重复观测之间的竞争
我有两个独立但重叠的用户交互流,它们都触发相同的操作。如果一个流启动,则在第一个流完成之前,另一个流不应启动。我可能想得太多了,但我找不到一个符合我要求的模式 具体示例: 我想为文本区域中的选择打开上下文菜单,其中包含两个单独的交互流:RxJS:可重复观测之间的竞争,rxjs,rxjs6,Rxjs,Rxjs6,我有两个独立但重叠的用户交互流,它们都触发相同的操作。如果一个流启动,则在第一个流完成之前,另一个流不应启动。我可能想得太多了,但我找不到一个符合我要求的模式 具体示例: 我想为文本区域中的选择打开上下文菜单,其中包含两个单独的交互流: 通过鼠标:按下鼠标->更改选择->向上鼠标 通过键盘:选择更改->超时(500毫秒) 如您所见,两个流在“Selection Changed”部分中重叠,但第一个和最后一个条件不同。当用键盘选择时,没有明确的结束条件,所以我依赖计时器。当用鼠标选择时,有一个明确
race()
只需完成即可。我试过这样的方法:
const openMenu$ = of(true).pipe(
startWith(race(a$, b$)),
exhaust(),
repeat()
);
或
或
但所有这些只是一遍又一遍地重复第一次观察到的现象。我没有办法重新开始比赛
有什么想法吗?还是我完全错了?一场简单的
比赛应该是可以重复的
从'rxjs'导入{defer,timer,race};
从“rxjs/operators”导入{map};
//随机时间小于3秒后将发出“0”的可观测值
const randomTime$=延迟(()=>计时器(Math.random()*3000));
//将在随机时间少于3秒后随机发出“a”
const a$=randomTime$.pipe(映射(()=>a');
//将在随机时间少于3秒后随机发出“b”
constb$=randomTime$.pipe(映射(()=>'b');
//比赛a$和b$$
const source$=race(a$,b$).pipe(
//重复比赛5次。
随机(5)
);
source$.subscribe(console.log);
在上述代码中,startWith
和排气
是不必要的<代码>比赛(a$,b$)。管道(repeat())
应该是您所需要的全部
我会检查第一个可观察到的东西是否总是在第二个之前发出。也许它有自己的
起点,或者某种同步发射,保证它“赢得”比赛。如果你与两个同步观测值竞争,第一个总是赢。为什么第三种方法不起作用?如果a$
首先发出,b$
将被取消订阅,然后当a$
最终完成时,应达到重复
,这将重新订阅a$
和b$
。你是对的,我在比赛后的观察值和管道出现问题。观察到的内容永远不会完成(这是设计的),但是比赛之后的管道也永远不会完成(因为来源没有完成),因此永远不会取消订阅,也永远不会触发重复,因此永远不会重新订阅。添加后,将(1)
放在正确的位置(尤其是在所有筛选之前),现在一切都正常工作。在溪流中思考对我来说还是陌生的。。。
const openMenu$ = of(true).pipe(
exhaustMap(() => race(a$, b$)),
exhaust(),
repeat()
);
const openMenu$ = race(a$, b$).pipe(
repeat()
);