Rxjs 如何检测一个可观察序列何时出现';经过一段时间后,t产生了一个值

Rxjs 如何检测一个可观察序列何时出现';经过一段时间后,t产生了一个值,rxjs,Rxjs,我有一个可观测到的,它将dragover事件节流350毫秒,并返回true,只要这些事件持续出现: Rx.Observable .fromEvent(document, 'dragover') .map(function () { return true; }) .throttle(350) .distinctUntilChanged() 我想知道在过去的350毫秒内是否没有发生dragover事件,并在发生时返回false。我该怎么做呢 我是否需要有一个单独的计时器,并在发生

我有一个可观测到的,它将
dragover
事件节流350毫秒,并返回
true
,只要这些事件持续出现:

Rx.Observable
  .fromEvent(document, 'dragover')
  .map(function () { return true; })
  .throttle(350)
  .distinctUntilChanged()
我想知道在过去的350毫秒内是否没有发生dragover事件,并在发生时返回
false
。我该怎么做呢


我是否需要有一个单独的计时器,并在发生
dragover
事件时重置它?我希望我能保持这种无状态。

好吧,我想我最终解决了我自己的问题。我拆下了油门操纵器。这是多余的,因为浏览器无论如何会将
dragover
事件限制350毫秒

我为dragover“开始”事件创建了一个源,为dragover“结束”事件创建了一个源。我给出了两个时间戳,以便将结束事件的创建时间与开始事件的创建时间进行比较:

var dragoverStart$ = Rx.Observable
  .fromEvent(this.dom, 'dragover')
  .timestamp()
  .pluck('timestamp');

var dragoverEnd$ = dragoverStart$
  .delay(350);

Rx.Observable
  .combineLatest(dragoverStart$, dragoverEnd$)
  .map(function (timestamps) {
    return timestamps[0] > timestamps[1];
  })
  .distinctUntilChanged()
  .subscribe(function (isDragging) {
    // ...
  });

有一个名为
timeout
的操作符可以执行此操作

Rx.Observable
  .fromEvent(document, 'dragover')
  .throttle(350)
  .map(true)
  .timeout(350, Rx.Observable.just(false))
  .distinctUntilChanged();
请注意,
timeout
将从源
Observable
取消订阅,并使用您传入的订阅,因此在重新订阅之前,您不会从该
Observable
获得任何进一步的结果

此外,我建议您将
map
操作放在
节流阀之后,以避免对不使用的值进行不必要的映射操作

我建议考虑一下,如果这些计时真的是你想要的,因为你的节流速度超过了350毫秒,那么在350毫秒的时候超时会留下很窄的余量。1/3秒的反应时间并不多,特别是对于用户而言。因为您已经有了一个下游
distinctUntilChanged
,您甚至不需要节流,因为只有当它从true变为false时,您才会发出值

编辑

如果您需要
可观察
继续,您可以使用
doWhile
repeat
重新订阅(我使用mousemove进行测试):


我更喜欢这个解决方案,而不是我刚刚发布的那个。我以前尝试过timeout操作符,但在从源代码取消订阅时遇到了您刚才描述的问题。有没有一种干净的重新订阅方式?
Rx.Observable.fromEvent(window, 'mousemove')
 .map(true)
 .timeout(1000, Rx.Observable.just(false))
 .repeat()//.doWhile(function() { return true; })
 .distinctUntilChanged()
 .subscribe(function(value) { console.log(value); });

//Outputs
/* Mouse starts moving */
// true 

/* Mouse stopped moving for 1 second */
// false

/* Mouse still not moving no emit */

/* Mouse starts moving again */
// true