我一直在玩RxJs试图在基于画布的白板上替换鼠标事件监听器。我的绘图效果很好,但出于某种原因,已完成的函数永远不会被调用。
它非常简单,基于RxJs文档中的鼠标事件示例。这是代码的摘录,您可以在此处查看完整版http://codepen.io/hanloong/pen/YyvqgM?editors=001
point = (start, prev, current) ->
start: {x: start.offsetX, y: start.offsetY}
previous: {x: prev.offsetX, y: prev.offsetY}
current: {x: current.offsetX, y: current.offsetY}
mouseup = Rx.Observable.fromEvent(document, 'mouseup')
mousemove = Rx.Observable.fromEvent(document, 'mousemove')
mousedown = Rx.Observable.fromEvent(document, 'mousedown')
mousedrag = mousedown.flatMap (start) ->
mousemove.zip mousemove.skip(1), (prev, current) ->
point(start, prev, current)
.takeUntil mouseup
liveDraw = Rx.Observer.create(
(pos) ->
console.log pos
# drawLine stage, shape, pos.previous, pos.current
, (err) ->
console.log "Error: #{err}"
, () ->
# never gets run
console.log 'Complete'
)
mousedrag.subscribe liveDraw
目标是在用户完成绘制后将完整路径发送到服务器,理想情况是在完成的回调中发生。此时还可以检索整个集合,还是应该在事件进入时构建另一个数组?
答案 0 :(得分:1)
问题在于您订阅了永远不会完成的Observable(mouseMove
)。 flatMap
运算符将吞下您解除鼠标按钮时生成的所有中间onCompleted
事件。
我建议您将绘图作为副作用执行,然后将所有事件收集到一个数组中并在最后发送它们。道歉我没有使用coffeescript所以这是在ES6中:
var mouseup = Rx.Observable.fromEvent(document, 'mouseup');
var mousemove = Rx.Observable.fromEvent(document, 'mousemove');
var mousedown = Rx.Observable.fromEvent(document, 'mousedown');
var mousedrag = mousedown.flatMap(start => {
return mousemove
//Pair up the events
.pairwise()
.takeUntil(mouseup)
//Draw each event as you receive it
.tap(p => drawLine(stage, shape, pos[0], pos[1]))
//Gather all the events from this drag
.toArray();
});
//Subscribe will now receive arrays for each drag that has occured
mousedrag.subscribe(sendDataToServer,
err => `Error: ${err}`);
要使用pairwise
运算符,您还需要包含rx.lite.coincidence.compat.js
文件。