如何在rxjs中组合一系列可观察量

时间:2017-11-26 19:44:44

标签: javascript typescript rxjs reactive-programming

我正在使用rxjs来处理一些复杂的鼠标手势。

其中一个问题是在拖动操作期间多次“摇动”鼠标(从左到右,从右到左,......)。

由于我不知道用户是从左边还是右边开始,我使用'race()'来接受先开始的。

我的问题是,当第一个“摇晃”观察者完成时,第二个已完成。

我在jsbin(Actual Results。)

上做了一个简化的例子

(在这个简化的例子中,我使用负数作为“鼠标左”,正数作为“鼠标右键”。)

这里展示了问题的核心......

  const subMouseMove = new Rx.Subject<number>();

  const obLeft = subMouseMove.filter(m => m < 0);
  const obRight = subMouseMove.filter(m => m >= 0);

  const get_obLeftUntilRight = () => obLeft.takeUntil(obRight);
  const get_obRightUntilLeft = () => obRight.takeUntil(obLeft);

  const get_obShake = () => Rx.Observable.race(get_obLeftUntilRight(), get_obRightUntilLeft()); 

  const obDragShakeAndDrop = Rx.Observable.concat(
    get_obShake(),
    get_obShake(),
  );

  //sending the following values to subMouseMove 
  [-1, -2, 3, 4, -5].forEach((v, i, a) => setTimeout(() => subMouseMove.next(v), i * 10));

问题是get_obShake()的两个实例都在同一时间完成。

我从jsbin获得的结果是:

Expected results

我希望我的结果是:

http://jsbin.com/wuzodog/4/edit?html,js,output

当我修改示例(Comparable)时,直接调用“左/右摇”和“右/左摇”,绕过“race()”,我得到'预期'输出。 / p>

有人可以解释为什么第二个摇动在第一个例子的早期完成了吗?

2 个答案:

答案 0 :(得分:2)

这很棘手,但你认为答案更合理。问题是 Race 也接受完成作为第一个获胜的Observable。

const get_obLeftUntilRight = () => obLeft.takeUntil(obRight);
const get_obRightUntilLeft = () => obRight.takeUntil(obLeft);

当我们查看这两个Observable时,如果有&#39; left&#39;事件,第一个将发出,第二个将立即完成。如果我们得到一个正确的&#39;第一个事件立即完成,第二个......

这可能是你想要的:

const get_obLeftUntilRight = () => obLeft.take(1).concat(obLeft.takeUntil(obRight));
const get_obRightUntilLeft = () => obRight.take(1).concat(obRight.takeUntil(obLeft));

答案 1 :(得分:-1)

两个jsBin输出之间的差异是

** NEXT: get_obShake2 = 4
第一个缺少

,因为race已经消除了它。

所以,并不是说第二次摇晃很早就完成了,它只是一个较短的序列。

添加一些timestamp()以查看它。

我不得不说,我不会觉得这段代码符合您的意图,但这可能是我缺乏理解。