我正在学习RxJs。我使用Angular2 rc3。 以下流可用,但它给我太多mousemove事件。我想使用时间(节流)或其他控制流来减慢速度。 我该怎么做?如何使用angular 2 + Typescript在RxJs中处理mousemove事件?
移动鼠标流,而不节流
const mouseMove$ = Observable.fromEvent<MouseEvent>(document, 'mousemove');
mouseMove$.subscribe(x => console.log(x)); // works great, many {mouse position object} 's
简单的解决方案:使用节流应该是这样的:
const mouseMove$ = Observable.fromEvent<MouseEvent>(document, 'mousemove');
const latestMouseEventEvery1Second$ = mouseMove$.sample(1000);
latestMouseEventEvery1Second$.subscribe(x => console.log(x)); // error
- 这样本()操作我已经采取了形式在这里:http://reactivex.io/documentation/operators/sample.html
但是这在角度2 - CLI项目中不起作用。 给了我这个错误:
***Argument of type 'number' is not assignable to parameter of type 'Observable<\any>'*** - notice i've put <\MouseEvent> when casting.
另一种更强大的方式来达到同样的效果,我觉得可能是流动的: 这将是巨大的,如果我们可以根据收到的物品发送最新mousemove item
从另一个流。任何流 - 由我们创造..
例如:
当我们从eachSecond$
流(=我们的“控制流”)收到一个新的项目(1,2,3 ......), - 我们发出donwstream(进入mouseMoveEachSecond$
) - 从mouseMove$
流收到的最新项目。
const eachSecond$ = Observable.timer(0, 1000); // starts at 0 and gives 1,2,3 as values each 1000 milliseconds.
const mouseMove$ = Observable.fromEvent<MouseEvent>(document, 'mousemove');
const mouseMoveEachSecond$ = Observable.merge(eachSecond$,mouseMove$)
.some magic operator I can't find()
// this could work like this:
// many mouse items are coming at a high rate from the mouse stream
// only a few items (1,2,3..) are coming form the eachSecond$ stream
//the logic: We send downstream **only one mouse item** (the last) for each new item that is coming form the eachSecond$ stream.
);
mouseMoveEachSecond$.subscribe(x => console.log(x));
// a { mouse position object } = mouse item - only when you move the mouse
// and no more than one {mouse position object} per second}
声音很简单。我发现这很难实现 - 形成我所能说的,这是因为应该以某种方式共享流的状态。有一种方法可以告诉已经发送了什么东西。
在mouseMoveEachSecond $中,项目按顺序依次出现。或者是一个数字或一个物体。您需要知道:
- 这是最后一位
time item
当您收到新的mouse item
。 - 当您收到新的
time item
时,哪一次是最后的mouse item
。
这将允许您:
- 不发送
mouse item
下游,当鼠标没有在屏幕上移动。 - 不发送
mouse item
下游,而没有新的time item
从eachSecond $流发布。
这可以使用全局变量来完成。但是,这不是RxJS的做事方式。我不知道如何存储上次发送的项目并在下一步中使用它。 Reduce运算符可以保持状态:从一个项目发布到另一个项目,但我们如何使用该属性来实现此行为?这些流必须被认为是无限的。嗯...应该是这2流合并更简单的方法..也许是太早了。我觉得我的脑子想不想到在流:)
因此奠定明确两个问题:
- 这是一些方法来节制角2中的鼠标移动流?
- 我可以使用另一个流来控制何时释放鼠标移动项目?如果是的话,这个“控制流”可以是任何流,或者有限制?
太谢谢你了:)
天才答案的人,谢谢! - 我失去了超过5个小时试图做到这一点 - 使用扫描运算符 - 保持各州之间的状态,所有这一切。我很高兴它非常简单。你知道一个快速的方法来扩展到多个控制流吗?就像你在做某件事之前等待多个承诺完成一样? – AIon
没问题!你可以看看使用'zip'或'forkJoin'组合控制流,以便它们只在每个流有值时发出。 – paulpdaniels