油门时间运算符的config参数如何工作? (ThrottleConfig)

时间:2019-07-16 14:30:26

标签: javascript typescript rxjs rxjs6

我已经读过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 }
    ???

3 个答案:

答案 0 :(得分: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);
});
<script src="https://unpkg.com/rxjs@7.1.0/dist/bundles/rxjs.umd.js"></script>

答案 1 :(得分:2)

throttleTime在收到新值且尚未受到限制时,将开始一个新的油门时间间隔(不发射任何物品的时间段)。 leadingtrailing指定是在油门时间间隔的开始还是结束时发射物品。

leading

发出在油门时间间隔开始处开始新的油门时间间隔的项目。

trailing

节气门时间间隔结束时,从源发送最后收到的项目。

可视化

https://rxviz.com/v/xOvKPypJ

{ leading: true, trailing: false }

source:               --0----1----2----3----4----5----6----7----8-- 
throttle interval:    --[~~~~~~~~~~~~~~~~~]-[~~~~~~~~~~~~~~~~~]-[~~ 
output:               --0-------------------4-------------------8--
{ leading: false, trailing: true }

source:               --0----1----2----3----4----5----6----7----8-- 
throttle interval:    --[~~~~~~~~~~~~~~~~~]-[~~~~~~~~~~~~~~~~~]-[~~ 
output:               --------------------3-------------------7----
{ leading: true, trailing: true }

source:               --0----1----2----3----4----5----6----7----8-- 
throttle interval:    --[~~~~~~~~~~~~~~~~~]-[~~~~~~~~~~~~~~~~~]-[~~  
output:               --0-----------------3-4-----------------7-8--
{ leading: false, trailing: false }

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

答案 2 :(得分:0)

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

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

根据官方说明here

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

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

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

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

我查看了 thinkrx.io 站点以了解节流时间行为,并且能够重现结果,但仍然需要一些时间来跟踪确切的行为。附上来自 ThinkRx 网站的带有标记的大理石图像。

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

enter image description here

在图片中,万一(Leading True)

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

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

对于 Trailing True 的配置设置,Timer spans 与基于 Lead True 登录完全相同,尽管它不是传递 First 值,而是等到 100 毫秒结束,然后传递最后一个值直到该点。

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

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