我正在使用rxjs来处理一些复杂的鼠标手势。
其中一个问题是在拖动操作期间多次“摇动”鼠标(从左到右,从右到左,......)。
由于我不知道用户是从左边还是右边开始,我使用'race()'来接受先开始的。
我的问题是,当第一个“摇晃”观察者完成时,第二个已完成。
上做了一个简化的例子(在这个简化的例子中,我使用负数作为“鼠标左”,正数作为“鼠标右键”。)
这里展示了问题的核心......
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获得的结果是:
我希望我的结果是:
http://jsbin.com/wuzodog/4/edit?html,js,output
当我修改示例(Comparable
)时,直接调用“左/右摇”和“右/左摇”,绕过“race()”,我得到'预期'输出。 / p>
有人可以解释为什么第二个摇动在第一个例子的早期完成了吗?
答案 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()
以查看它。
我不得不说,我不会觉得这段代码符合您的意图,但这可能是我缺乏理解。