【问题标题】:RxJS Observables and a wheel eventRxJS Observables 和轮子事件
【发布时间】:2020-07-23 17:09:04
【问题描述】:

我想知道是否有人可以帮助我从理论上提出解决方案。我从一个车轮事件创建一个 Observable,阻止默认操作,将其限制 200 毫秒,映射 deltaY(我可以用它来确定方向),然后我分享它。

我的问题是它发出的值超出了我的需要,从而造成即使在发生所需操作后我的订阅者仍会继续触发的情况。我是 RxJS 的新手,所以请多多包涵,但是......有没有办法让我在 X 时间内获取一系列值中发出的“第一个”值并且没有可观察到的完整值?

下面是代码。

import { fromEvent } from 'rxjs';

const wheel$ = fromEvent(document, 'wheel')
    .pipe(
        tap((event) => event.preventDefault()),
        // throttleTime(200), /* I have tried throttling and debouncing but that doesn't work - values will continue to be emitted */
        map((event) => event.deltaY),
        share()
    )

 // handles scrolling down //
 wheel$.pipe(filter((val) => val > 0))
     .subscribe((event) => {
         if (this.props.isScrolling) return
         this.scrollDown();
     })

【问题讨论】:

  • 这很有趣。我试过了,它也对我不起作用,但是当我将事件从滚轮更改为单击时,throttleTime 工作。
  • 我的错,文件一定没有保存,刷新 Stackblitz 工作。在应用中滚动时查看控制台日志here
  • @SamHerrmann 感谢您花时间解决这个问题。我看了你的 Stackblitz ......如果你执行一个明显的滚动,第二个事件将在其中不解决这个问题。

标签: rxjs reactive-programming


【解决方案1】:

一种解决方案是“bufferCount()”

of(1,2,3,4,5,6,7,8,9).pipe(
  bufferCount(3)
).subscribe(data => console.log(data) )

将创建 3 个信号包。所以事件将是

[1,2,3]
[4,5,6]
[7,8,9]

或者“throttleTime(xy)”,而不是让第一个信号通过,每隔一个信号将忽略“xy”毫秒,然后给下一个信号一个机会。

interval(500).pipe(
  throttleTime(2000)
).subscribe(data => console.log(data) )

会导致类似

1 // ignore everything the next 2 seconds
5 // ignore everything the next 2 seconds
9 // ignore everything the next 2 seconds
...

热烈的问候

【讨论】:

  • bufferCount 在这里也不好。基本上问题是轮子事件将导致可观察者在一次爆发中发出大约 20 - 50 个连续事件。因此,我的订阅者将执行,但由于事件仍在订阅者中泛滥,将继续被触发。
  • 不完全是。您的订阅者将获得更少的事件。但在这些事件中,信息更加丰富。如果您的订阅者确实想要控制他们想要处理的内容和数量,这很好。作为提供商,您可以定义他们获得更新的频率。 --- 当接受忽略信息时,尝试“节流”(learnrxjs.io/operators/filtering/throttle.html
  • 谢谢!我仍在努力研究反应式编程,但您的评论很有帮助。
【解决方案2】:

在寻找解决方案时发现了这个问题。 我用的是 switchMap

fromEvent(el, 'wheel').pipe(
  switchMap(e => 
    concat(
      //wrap the original event, which fires immediately
      of({kind: 'ON_WHEEL', e}),
      // fire a onWheelEnd after a 200ms delay
      // this event is unsubscribed by the switchMap if a new event comes in
      // before the delay
      of({kind: 'ON_WHEEL_END}).pipe(delay(200))
    )
  )
)

【讨论】:

    猜你喜欢
    • 2017-05-30
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多