【问题标题】:How does throttleTime operator's config parameter work? (ThrottleConfig)throttleTime 算子的 config 参数是如何工作的? (油门配置)
【发布时间】:2019-11-25 07:58:24
【问题描述】:

我已经阅读了throttleTime documentation,但我没有完全理解运营商。

我知道throttleTime(1000) 的工作原理。事件到达后,它将跳过所有后续事件 1 秒钟,然后重新开始此过程。

我很难理解的是 ThrottleConfig 究竟是如何工作的,这是运算符的第三个参数。

throttleTime<T>(
  duration: number, 
  scheduler: SchedulerLike = async, 
  config: ThrottleConfig = defaultThrottleConfig): MonoTypeOperatorFunction<T>

leadingtrailing 属性如何改变源 Observable 的功能?

我已经阅读了很多文档,但他们没有清楚地解释这一点。

所以有四种选择:

  1. { leading: true, trailing: false }:
    默认选项,接收到事件后会跳过指定持续时间的其他事件,然后重复。
  2. { leading: false, trailing: true }:
    ???
  3. { leading: false, trailing: false }:
    对此进行了测试,Observable 根本没有发出任何东西。
  4. { leading: true, trailing: true }:
    ???

【问题讨论】:

    标签: javascript typescript rxjs rxjs6


    【解决方案1】:

    throttleTime 将在收到新值且尚未受到限制时开始一个新的限制间隔(不会发出任何项目的时间段)。此节流间隔的长度由您提供的持续时间决定。

    在 RxJS 7 中,当在 节流间隔 结束时发出尾随值时,也会启动新的 节流间隔

    leadingtrailing 指定是否应在节流间隔的开头或结尾发出项目。

    leading: 在新的节流间隔开始时发出一个项目。

    trailing:限制间隔结束时发出从源接收到的最后一项。

    可视化

    RxJS 6 和 7 - trailing: false

    throttleTime(12 ticks, { leading: true, trailing: false })
    
    source_1:           --0--1-----2--3----4--5-6---7------------8-------9---------
    throttle interval:  --[~~~~~~~~~~~]----[~~~~~~~~~~~]---------[~~~~~~~~~~~]-----
    output_1:           --0----------------4---------------------8-----------------
    
    
    source_2:           --0--------1------------------2--------------3---4---------
    throttle interval:  --[~~~~~~~~~~~]---------------[~~~~~~~~~~~]--[~~~~~~~~~~~]-
    output_2:           --0---------------------------2--------------3-------------
    
    throttleTime(12 ticks, { leading: false, trailing: false })
    
    source_1:           --0--1-----2--3----4--5-6---7------------8-------9---------
    throttle interval:  --[~~~~~~~~~~~]----[~~~~~~~~~~~]---------[~~~~~~~~~~~]-----
    output_1:           -----------------------------------------------------------
    
    
    source_2:           --0--------1------------------2--------------3---4---------
    throttle interval:  --[~~~~~~~~~~~]---------------[~~~~~~~~~~~]--[~~~~~~~~~~~]-
    output_2:           -----------------------------------------------------------
    

    RxJS 6 - trailing: true

    throttleTime(12 ticks, { leading: true, trailing: true })
    
    source_1:           --0--1-----2--3----4--5-6---7------------8-------9---------
    throttle interval:  --[~~~~~~~~~~~]----[~~~~~~~~~~~]---------[~~~~~~~~~~~]-----
    output_1:           --0-----------3----4-----------7---------8-----------9-----
    
    
    source_2:           --0--------1------------------2--------------3---4---------
    throttle interval:  --[~~~~~~~~~~~]---------------[~~~~~~~~~~~]--[~~~~~~~~~~~]-
    output_2:           --0-----------1---------------2--------------3-----------4-
    
    throttleTime(12 ticks, { leading: false, trailing: true })
    
    source_1:           --0--1-----2--3----4--5-6---7------------8-------9---------
    throttle interval:  --[~~~~~~~~~~~]----[~~~~~~~~~~~]---------[~~~~~~~~~~~]-----
    output_1:           --------------3----------------7---------------------9-----
    
    
    source_2:           --0--------1------------------2--------------3---4---------
    throttle interval:  --[~~~~~~~~~~~]---------------[~~~~~~~~~~~]--[~~~~~~~~~~~]-
    output_2:           --------------1---------------------------2--------------4-
    

    RxJS 7 - trailing: true

    throttleTime(12 ticks, { leading: true, trailing: true })
    
    source_1:           --0--1-----2--3----4--5-6---7------------8-------9---------
    throttle interval:  --[~~~~~~~~~~~I~~~~~~~~~~~I~~~~~~~~~~~I~~~~~~~~~~~I~~~~~~~~
    output:             --0-----------3-----------6-----------7-----------9--------
    
    
    source_2:           --0--------1------------------2--------------3---4---------
    throttle interval:  --[~~~~~~~~~~~I~~~~~~~~~~~]---[~~~~~~~~~~~]--[~~~~~~~~~~~I~
    output_2:           --0-----------1---------------2--------------3-----------4-
    
    throttleTime(12 ticks, { leading: false, trailing: true })
    
    source_1:           --0--1-----2--3----4--5-6---7------------8-------9---------
    throttle interval:  --[~~~~~~~~~~~I~~~~~~~~~~~I~~~~~~~~~~~I~~~~~~~~~~~I~~~~~~~~
    output:             --------------3-----------6-----------7-----------9--------
    
    
    source_2:           --0--------1------------------2--------------3---4---------
    throttle interval:  --[~~~~~~~~~~~I~~~~~~~~~~~]---[~~~~~~~~~~~I~~~~~~~~~~~]----
    output_2:           --------------1---------------------------2-----------4----
    

    【讨论】:

    • 有人需要将这个答案放在官方文档上,前导,尾随... WTF?!谢谢。顺便说一句,您的可视化现在是一个死链接
    • Rxjs 7 中 {leading: true, trailing: true} 情况的行为发生了变化。它现在将始终确保输出事件之间的间距受到限制。 github.com/ReactiveX/rxjs/commit/…
    【解决方案2】:

    当Source observable不是固定时间间隔内的序列号时,这个问题可能需要更详细的解释。

    官网的解释是针对场景的 {leading: true, trailing: false },这也是默认行为。

    根据here官方解释

    有一个内部计时器,具有启用和禁用两种状态。

    当定时器启用时,没有值可以通过。

    当定时器被禁用时,一旦第一个源值到达(在定时器禁用事件之后)该值被转发到输出 observable,然后定时器被启用。它在持续时间参数中指定的时间跨度内保持启用状态。

    这里要注意的重要事实是 Timer 被禁用的时间跨度不是固定的,它取决于源 observable 值的到达。 (如下图所示)

    我查看了thinkrx.io 站点的油门时间行为,并能够重现结果,但仍需要一些时间来追踪确切的行为。将来自 ThinkRx 网站的大理石图像附上标记。

    请注意,在 ThinkRx 大理石图中,颜色代表可观察值,数字代表时间实例。

    在图像中,如果是(Leading True)

    红色水平标记是启用定时器时(没有值可以通过) 绿色水平标记是定时器被禁用时。请注意,定时器被禁用的时间多于或少于 100 毫秒。

    最初定时器被禁用,它允许 0 通过并被启用。 100ms 后它被禁用并保持该状态直到 230, 通过 230 并再次启用,依此类推。

    对于 Trailing True 的配置设置,Timer span 与 Leading True 登录完全相同,但不是传递 First 值,而是等到 100ms 结束,然后传递最后一个值直到该点。

    对于两者都为真,它传递前导和尾随两个值

    两个 false 都不通过任何东西。

    【讨论】:

      【解决方案3】:

      { leading: true, trailing: true } 的预期输出在 rxjs 7 中发生了变化: https://github.com/ReactiveX/rxjs/commit/ea84fc4dce84e32598701f79d9449be00a05352c

      它现在将确保节流阀之间的间距始终至少是节流量。

      因此,如果有尾随发射,油门间隔将立即重复。这使得@frido 中的示例变为如下所示:

      source:              --0--1-----2--3----4--5-6---7------------8-------9--------
      throttle interval:   --[~~~~~~~~~~~x~~~~~~~~~~~x~~~~~~~~~~~x~~~~~~~~~~~x~~~~~~~
      output:              --0-----------3-----------6-----------7-----------9-------
      

      我用下面的有效测试用例从@frido 重新创建了示例。

      const testScheduler = new rxjs.testing.TestScheduler((actual, expected) => {
        const actualString = JSON.stringify(actual);
        const expectedString = JSON.stringify(expected)
        console.log(actualString)
        console.log(expectedString);
        console.log(expectedString === actualString);
      });
      testScheduler.run((helpers) => {
        const { cold, time, expectObservable, expectSubscriptions } = helpers;
        const e1 = cold(' --0--1-----2--3----4--5-6---7------------8-------9--------|');
        const expected = '--0-----------3-----------6-----------7-----------9-------|';
        const e1subs = '  ^---------------------------------------------------------!';
        const t = time('  ------------|'); // t = 12
      
        expectObservable(e1.pipe(
            rxjs.operators.throttleTime(t, null, { leading: true, trailing: true })
        )).toBe(expected);
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
      });
      &lt;script src="https://unpkg.com/rxjs@7.1.0/dist/bundles/rxjs.umd.js"&gt;&lt;/script&gt;

      【讨论】:

      • 谢谢,这有助于注意新版本有更新的功能
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-16
      • 1970-01-01
      • 2020-09-12
      • 2013-03-10
      相关资源
      最近更新 更多