【问题标题】:What does RxJS.Observable debounce do?RxJS.Observable debounce 有什么作用?
【发布时间】:2015-08-30 15:47:48
【问题描述】:

谁能用简单的英语解释一下RxJS Observable debounce function 的作用?

我想它会根据参数不时发出一个事件,但我下面的代码没有按预期工作。

var x$ = Rx.Observable.fromEvent(window, 'click')
    .map(function(e) {return {x:e.x, y:e.y};})
    .debounce(1000)
    .subscribe(function(el) {
      console.log(el);
    });

the JsBin version

我希望这段代码每秒打印一次点击,无论我点击多快。相反,它会以我认为的随机间隔打印点击。

【问题讨论】:

  • 仅供参考,rxmarbles website 可以提供帮助。这是一项正在进行的工作,并没有所有的运算符,但它确实有 debounce :)
  • @Brandon 我的回答中有一个链接 :-)

标签: javascript rxjs debouncing


【解决方案1】:

长话短说: debounce 等待 X 时间流没有发出任何新值,然后让最新的值通过。

长篇大论: 一旦发出一个值,debounce 将暂停其发射 X 时间,以查看是否发出另一个值,实际上在此期间阻塞流。如果在 debounce 时间内发出一个新值,则计时器将重新启动并 debounce 再次等待完整时间。 如果它的计时器到期而没有发出任何新值,它会让最新的值通过。

假设您要向输入框添加自动完成功能。如果用户插入“a”,您可能希望向他显示选项“acorn, alaska”,但如果用户在按下“l”后立即提出“alaska”。在这种情况下,最好等待用户停止按下键盘以避免做不必要的工作。 debounce 这是正确的工具:它等待 X 时间流没有发出任何新值

【讨论】:

    【解决方案2】:

    Debounce 将在指定的时间间隔过后发出一个值,而不会发出另一个值。

    使用以下简单的图表可能会提供更大的帮助:

    Stream 1 | ---1-------2-3-4-5---------6----
    
        after debounce, the emitted stream looks like as follows:
    
    Stream 2 | ------1-------------5---------6-
    

    中间项(在本例中为 2、3、4)被忽略。

    一个例子如下所示:

    var Rx = require('rx-node');
    var source = Rx.fromStream(process.stdin).debounce(500);
    var subscription = source.subscribe(
        function (x) {
            console.log('Next: %s', x);
        }
    );
    

    我用 node 来说明这一点...假设你已经安装了 node,你可以通过键入来运行它

    $node myfile.js  (where the aforementioned code is in myfile.js)
    

    一旦这个节点程序启动,你可以在控制台输入值——如果你快速输入,项目会被忽略,如果输入间歇性快速和慢速项目会在输入间隙后出现(在上面的例子中,我有 500 毫秒)在控制台(“下一步:”)

    https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/debounce.md也有一些优秀的参考资料

    【讨论】:

    • 这个答案有助于理解debounce,而上一个答案为我的问题提供了解决方案。
    • @Adrian 这个答案再现了完全相同的图表,我提供了一个链接。
    • 确实如此。在问这个问题之前,我看了很多 rxmarbles。这就是我要求简单英语的原因。
    【解决方案3】:

    如果在指定的时间间隔内没有收到任何值,.debounce() 将生成最后收到的值。

    这意味着只要你在一秒钟内点击 - 什么都不会产生。

    如果您希望限制值的发出频率不超过每秒,您需要改用.sample(1000)

    【讨论】:

    • throttileFirst 是另一个不错的选择:当您第一次单击时,它会立即发出单击事件,但随后会忽略接下来 X 毫秒内的所有单击。
    • @Brandon 哦,有很多不同的运算符可用。谢谢
    猜你喜欢
    • 2013-04-02
    • 2018-04-12
    • 2020-11-10
    • 1970-01-01
    • 1970-01-01
    • 2021-09-23
    • 2019-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多