Rx 问题一则 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
node
V2EX    程序员

Rx 问题一则

  •  
  •   node 2017-04-10 18:36:57 +08:00 3489 次点击
    这是一个创建于 3105 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    12 条回复    2017-04-10 23:46:26 +08:00
    jackisnotspirate
        1
    jackisnotspirate  
       2017-04-10 20:06:49 +08:00 via iPhone
    不太明白,能不能讲一讲什么场景
    node
        2
    node  
    OP
       2017-04-10 20:44:28 +08:00
    @jackisnotspirate
    是要发送一个同步信息用的网络请求,一般情况下一小时请求一次就够了,采用某种同步方式来触发(比如所有的点击事件),所有一小时间隔以内的触发都屏蔽掉,但是有某个按钮在点击后必须立即发送这个网络请求,这次请求完成后,也是在之后的一个小时内屏蔽掉其它的普通触发
    SoloCompany
        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));
    node
        4
    node  
    OP
       2017-04-10 21:55:06 +08:00
    @SoloCompany
    好像不行,这个 interval 只能设定往后时间的定时器,也就是说普通触发往后一秒无论如何都会被锁死,普通的和特殊的都是,而反过来特殊触发之后的任何触发都会被接受,也是普通的和特殊的都是
    jackisnotspirate
        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))
    )
    ```
    jackisnotspirate
        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 。 代码你要修改一下,只是大概表达一下思路
    node
        7
    node  
    OP
       2017-04-10 22:46:40 +08:00
    @jackisnotspirate
    非常感谢啊,这样说起来的确有些思路了,但是废立定时器和 throttle 怎么结合还是有点不明白,能再具体些吗?
    SoloCompany
        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));
    SoloCompany
        9
    SoloCompany  
       2017-04-10 23:00:41 +08:00   1
    还是有一点小问题,但不难修正
    就是让 buttonA 按下的同时,不但要给 timer 推一个事件
    还要 unsubscribe 掉之前的计时器, 重新 subscribe 一个新的计时器
    以确保时钟要重新计算
    jackisnotspirate
        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 没关系
    NxiJSiOS
        11
    NxiJSiOS  
       2017-04-10 23:31:25 +08:00
    @jackisnotspirate RxSwift 大神?
    node
        12
    node  
    OP
       2017-04-10 23:46:26 +08:00
    @SoloCompany
    嗯,谢谢,不过最好能一气呵成,更 rx 些,其实考虑 unsubscribe 的话,直接在特殊触发后废立一次 subscription 就好了

    @jackisnotsirate
    请问能用代码演示一下吗?因为之前的代码里没有出现特殊触发事件,假设普通触发是 fromEvent(buttonPlain, 'click'),特殊触发是 fromEvent(buttonSpecial, 'click')这样
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     6029 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 02:12 PVG 10:12 LAX 19:12 JFK 22:12
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86