Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/google-sheets/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
RxJS:可重复观测之间的竞争_Rxjs_Rxjs6 - Fatal编程技术网

RxJS:可重复观测之间的竞争

RxJS:可重复观测之间的竞争,rxjs,rxjs6,Rxjs,Rxjs6,我有两个独立但重叠的用户交互流,它们都触发相同的操作。如果一个流启动,则在第一个流完成之前,另一个流不应启动。我可能想得太多了,但我找不到一个符合我要求的模式 具体示例: 我想为文本区域中的选择打开上下文菜单,其中包含两个单独的交互流: 通过鼠标:按下鼠标->更改选择->向上鼠标 通过键盘:选择更改->超时(500毫秒) 如您所见,两个流在“Selection Changed”部分中重叠,但第一个和最后一个条件不同。当用键盘选择时,没有明确的结束条件,所以我依赖计时器。当用鼠标选择时,有一个明确

我有两个独立但重叠的用户交互流,它们都触发相同的操作。如果一个流启动,则在第一个流完成之前,另一个流不应启动。我可能想得太多了,但我找不到一个符合我要求的模式

具体示例:

我想为文本区域中的选择打开上下文菜单,其中包含两个单独的交互流:

  • 通过鼠标:按下鼠标->更改选择->向上鼠标
  • 通过键盘:选择更改->超时(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()
    );