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