如何检测可观察序列何时在一段时间后未生成值

时间:2015-10-13 17:13:32

标签: rxjs

我有一个可观察量,将dragover个事件限制为350毫秒,只要这些事件继续进入,就会返回true

Rx.Observable
  .fromEvent(document, 'dragover')
  .map(function () { return true; })
  .throttle(350)
  .distinctUntilChanged()

我想知道在过去的350毫秒内是否没有一个dragover事件,并在发生这种情况时返回false。我应该怎么做呢?

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

2 个答案:

答案 0 :(得分:3)

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

Rx.Observable
  .fromEvent(document, 'dragover')
  .throttle(350)
  .map(true)
  .timeout(350, Rx.Observable.just(false))
  .distinctUntilChanged();

请注意timeout取消订阅来源Observable并订阅您传入的内容,因此您无法从Observable获得任何进一步的结果,直到您的重新订阅它。

另外,我建议您在map 之后放置throttle操作,以避免对您不会使用的值进行不必要的映射操作。

我建议考虑一下这些时间是否真的是你想要的,因为你节流超过350毫秒,超过350毫秒的时间会留下一些相当窄的边缘。 1/3秒不是很多时间特别对用户做出反应。由于你已经有了一个下游distinctUntilChanged,你可能甚至不需要加油,因为你只会在从true变为false时发出值。

修改

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

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

答案 1 :(得分:0)

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

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

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) {
    // ...
  });