假设有一个输入源,后面接 throttle 操作符来控制输出的时间间隔,像这样
var clicks = Rx.Observable.fromEvent(document, 'click'); var result = clicks.throttleTime(1000); result.subscribe(x => console.log(x));
另有一路输入源是突发型的,来了之后不受 throttle 的限制,直接向后输出,并且能重置之前普通输入源在 throttle 里面的计时器,请问这个需求该怎么实现呢?
1
jackisnotspirate 2017-04-10 20:06:49 +08:00 via iPhone
不太明白,能不能讲一讲什么场景
|
2
node OP @jackisnotspirate
是要发送一个同步信息用的网络请求,一般情况下一小时请求一次就够了,采用某种同步方式来触发(比如所有的点击事件),所有一小时间隔以内的触发都屏蔽掉,但是有某个按钮在点击后必须立即发送这个网络请求,这次请求完成后,也是在之后的一个小时内屏蔽掉其它的普通触发 |
3
SoloCompany 2017-04-10 21:36:02 +08:00
var buttonA = ...
Rx.Observable.fromEvent(document, 'click') .throttle(ev => Rx.Observable.interval(ev.source = buttonA ? 0 : 1000)) .subscribe(x => console.log(x)); |
4
node OP @SoloCompany
好像不行,这个 interval 只能设定往后时间的定时器,也就是说普通触发往后一秒无论如何都会被锁死,普通的和特殊的都是,而反过来特殊触发之后的任何触发都会被接受,也是普通的和特殊的都是 |
5
jackisnotspirate 2017-04-10 22:01:58 +08:00 1
```
Rx.Observable.interval(1000).takeUntil( Rx.Observable.fromEvent(document, 'click') .throttle .flatMapLatest (Rx.Observable.interval(1000)) ) ``` |
6
jackisnotspirate 2017-04-10 22:05:04 +08:00 1
先建一个定时器,然后每次点击会产生一个新的定时器,废掉最开始的定时器, takeUntil 是从 RxSwift 里面找的, Emits elements from a source Observable sequence until a reference Observable sequence emits an element.
你可以看下对应功能 RxJS 里面的 operator 。 代码你要修改一下,只是大概表达一下思路 |
7
node OP @jackisnotspirate
非常感谢啊,这样说起来的确有些思路了,但是废立定时器和 throttle 怎么结合还是有点不明白,能再具体些吗? |
8
SoloCompany 2017-04-10 22:52:31 +08:00 1
@node 可以用 sample ,和 throttle 的差别是一个是定时触发,另一个是阀门(触发时间接近严格等于事件源时间)
先建一个可干预的定时器 var timer = new Rx.Subject(); Rx.Observable.interval(1000).subscribe(timer); // 每秒触发一次 Rx.Observable.fromEvent(buttonA, 'click').subscribe(timer); // button A 按下也触发一次 // 用这个可干预的定时器来控制事件触发频率 var result = timer.sample(Rx.Observable.fromEvent(document, 'click')); result.subscribe(x => console.log(x)); |
9
SoloCompany 2017-04-10 23:00:41 +08:00 1
还是有一点小问题,但不难修正
就是让 buttonA 按下的同时,不但要给 timer 推一个事件 还要 unsubscribe 掉之前的计时器, 重新 subscribe 一个新的计时器 以确保时钟要重新计算 |
10
jackisnotspirate 2017-04-10 23:07:38 +08:00 1
@node takeUnti 相当于废掉最先的那个 Rx.Observable.interval(1000), flatMapLatest 会废掉这次 click 之前,也就是上一次 click 生成的 timer (这个 timer 能马上执行一次,并间隔执行,需要自己替换), throttle 只是改变了 click 生成 timer 的频率,跟废除 timer 没关系
|
11
NxiJSiOS 2017-04-10 23:31:25 +08:00
@jackisnotspirate RxSwift 大神?
|
12
node OP @SoloCompany
嗯,谢谢,不过最好能一气呵成,更 rx 些,其实考虑 unsubscribe 的话,直接在特殊触发后废立一次 subscription 就好了 @jackisnotspirate 请问能用代码演示一下吗?因为之前的代码里没有出现特殊触发事件,假设普通触发是 fromEvent(buttonPlain, 'click'),特殊触发是 fromEvent(buttonSpecial, 'click')这样 |