Rx 问题一则

2017-04-10 18:36:57 +08:00
 node

假设有一个输入源,后面接 throttle 操作符来控制输出的时间间隔,像这样

var clicks = Rx.Observable.fromEvent(document, 'click'); var result = clicks.throttleTime(1000); result.subscribe(x => console.log(x));

另有一路输入源是突发型的,来了之后不受 throttle 的限制,直接向后输出,并且能重置之前普通输入源在 throttle 里面的计时器,请问这个需求该怎么实现呢?

2882 次点击
所在节点    程序员
12 条回复
jackisnotspirate
2017-04-10 20:06:49 +08:00
不太明白,能不能讲一讲什么场景
node
2017-04-10 20:44:28 +08:00
@jackisnotspirate
是要发送一个同步信息用的网络请求,一般情况下一小时请求一次就够了,采用某种同步方式来触发(比如所有的点击事件),所有一小时间隔以内的触发都屏蔽掉,但是有某个按钮在点击后必须立即发送这个网络请求,这次请求完成后,也是在之后的一个小时内屏蔽掉其它的普通触发
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));
node
2017-04-10 21:55:06 +08:00
@SoloCompany
好像不行,这个 interval 只能设定往后时间的定时器,也就是说普通触发往后一秒无论如何都会被锁死,普通的和特殊的都是,而反过来特殊触发之后的任何触发都会被接受,也是普通的和特殊的都是
jackisnotspirate
2017-04-10 22:01:58 +08:00
```
Rx.Observable.interval(1000).takeUntil(
Rx.Observable.fromEvent(document, 'click')
.throttle
.flatMapLatest (Rx.Observable.interval(1000))
)
```
jackisnotspirate
2017-04-10 22:05:04 +08:00
先建一个定时器,然后每次点击会产生一个新的定时器,废掉最开始的定时器, takeUntil 是从 RxSwift 里面找的, Emits elements from a source Observable sequence until a reference Observable sequence emits an element.
你可以看下对应功能 RxJS 里面的 operator 。 代码你要修改一下,只是大概表达一下思路
node
2017-04-10 22:46:40 +08:00
@jackisnotspirate
非常感谢啊,这样说起来的确有些思路了,但是废立定时器和 throttle 怎么结合还是有点不明白,能再具体些吗?
SoloCompany
2017-04-10 22:52:31 +08:00
@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));
SoloCompany
2017-04-10 23:00:41 +08:00
还是有一点小问题,但不难修正
就是让 buttonA 按下的同时,不但要给 timer 推一个事件
还要 unsubscribe 掉之前的计时器, 重新 subscribe 一个新的计时器
以确保时钟要重新计算
jackisnotspirate
2017-04-10 23:07:38 +08:00
@node takeUnti 相当于废掉最先的那个 Rx.Observable.interval(1000), flatMapLatest 会废掉这次 click 之前,也就是上一次 click 生成的 timer (这个 timer 能马上执行一次,并间隔执行,需要自己替换), throttle 只是改变了 click 生成 timer 的频率,跟废除 timer 没关系
NxiJSiOS
2017-04-10 23:31:25 +08:00
@jackisnotspirate RxSwift 大神?
node
2017-04-10 23:46:26 +08:00
@SoloCompany
嗯,谢谢,不过最好能一气呵成,更 rx 些,其实考虑 unsubscribe 的话,直接在特殊触发后废立一次 subscription 就好了

@jackisnotspirate
请问能用代码演示一下吗?因为之前的代码里没有出现特殊触发事件,假设普通触发是 fromEvent(buttonPlain, 'click'),特殊触发是 fromEvent(buttonSpecial, 'click')这样

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/353886

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX