使用angular 2 + Typescript时如何在RxJs中限制mousemove事件?

时间:2016-07-28 15:18:13

标签: typescript angular stream rxjs

我正在学习RxJs。我使用Angular2 rc3。 以下流有效,但它为我提供了过多的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

- 这个 sample()运算符我在这里采取了表格: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$流(=我们的&#34;控制流&#34;)收到新项目(1,2,3 ..)时, - 我们发出donwstream(进入{{1 }}) - 从mouseMoveEachSecond$流收到的最新项目。

mouseMove$

听起来很简单。我发现这特别难以实现 - 形成我能说的,这是因为流的状态应该以某种方式共享。需要一种告诉已发送内容的方法..

在mouseMoveEachSecond $中,项目按顺序逐个进行。或者数字或对象。你需要知道:

  • 当您收到新的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} 时,这是最后一次time item
  • 当您收到新的mouse item时,这是最后一次mouse item

这将使您能够:

  • 当鼠标在屏幕上移动时,不会向{... 1}下游发送。
  • 虽然没有从eachSecond $ stream发布新time item,但不向{... 1}下游发送。

这可以使用全局变量来完成。但这不是RxJS的做法。我不知道如何存储最后发送的项目并在下一步中使用它。减少运算符可以保持状态:从一个项目发布到另一个项目,但我们如何使用该属性来实现此行为?这些流必须被认为是无限的。嗯...应该是更简单的方法来结合这两个流..也许是太早了...我觉得我的大脑不想在Streams中思考:)

所以这两个问题很明确:

  1. 哪些方法可以用角度2来节流鼠标移动?
  2. 我可以使用其他流来控制何时释放mousemove项目?如果是,那么这个&#34;控制流&#34;可以是任何流,还是有局限性的?
  3. 非常感谢你:)

3 个答案:

答案 0 :(得分:5)

你非常亲密!具有讽刺意味的是,您的魔术运算符 sample

样本的旧变体(来自RxJS4)被重载并且可以将数字作为其参数。在RxJS5(与Angular2一起提供的那个)中,它已被拆分,因此实际上有两个运算符samplesampleTime。后者是一个需要时间参数并在发出时在给定时间窗口中获取最后一个事件。

const mouseMoveEachSecond$ = mouseMove$.sampleTime(1000);

前者将Observable作为唯一参数,并在每次控件Observable发出时发出最后一项。

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$ = mouseMove$.sample(eachSecond$);

mouseMoveEachSecond$.subscribe( x => console.log(x)); 

答案 1 :(得分:0)

如何导入节流时间:

import { throttleTime } from 'rxjs/operators';

,然后按以下方式使用它:

mousemouve$.pipe(
      throttleTime(5000)
    )

答案 2 :(得分:-1)

您的魔术运算符看起来应该是flatMapselectMany

另请参阅takeUntil

查看https://stackoverflow.com/a/30314492/1267942了解详情。