javascript - RxJS:使用常规采样去抖动

标签 javascript rxjs

我有一个 Observable,它从用户输入( slider 的偏移值)发出值流。

我想反跳那个流,所以当用户忙于滑动时,我只在没有任何东西通过时发出一个值,比如 100 毫秒,以避免被值淹没。但是如果它只是无休止地去抖动(用户连续来回滑动),我也想每 1 秒发出一个值。不过,一旦用户停止滑动,我只需要去抖动流中的最终值。

所以我想将去抖动与流的常规“采样”结合起来。现在我的设置是这样的:

const debounce$ = slider$.debounceTime(100),
      sampler$ = slider$.auditTime(1000);

debounce$
    .merge(sampler$)
    .subscribe((value) => console.log(value));

假设用户移动 slider 2.4 秒,这将发出如下值:

 start                      end
  (x)---------|---------|---(x)|----|
              |         |      |    |
             1.0       2.0    2.5  3.0  <-- unwanted value at the end
              ^         ^      ^
            sample   sample   debounce  <-- these are all good

我不希望在 3 秒时发出额外的值(来自 sampler$ 流)。

显然 merge 是组合这两个流的错误方式,但我想不通 switchrace 是什么组合, 窗口 或此处使用的任何内容。

最佳答案

您可以通过编写用作信号的可观察对象来解决该问题,指示用户当前是否正在滑动。应该这样做:

const sliding$ = slider$.mapTo(true).merge(debounce$.mapTo(false));

您可以使用它来控制 sampler$ 是否发出值。

一个工作示例:

const since = Date.now();
const slider$ = new Rx.Subject();

const debounce$ = slider$.debounceTime(100);
const sliding$ = slider$.mapTo(true).merge(debounce$.mapTo(false));

const sampler$ = slider$
  .auditTime(1000)
  .withLatestFrom(sliding$)
  .filter(([value, sliding]) => sliding)
  .map(([value]) => value);

debounce$
  .merge(sampler$)
  .subscribe(value => console.log(`${time()}: ${value}`));

// Simulate sliding:

let value = 0;
for (let i = 0; i <= 2400; i += 10) {
  value += Math.random() > 0.5 ? 1 : -1;
  slide(value, i);
}

function slide(value, at) {
  setTimeout(() => slider$.next(value), at);
}

function time() {
  return `T+${((Date.now() - since) / 1000).toFixed(3)}`;
}
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://unpkg.com/rxjs@5/bundles/Rx.min.js"></script>

关于javascript - RxJS:使用常规采样去抖动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45777683/

相关文章:

javascript - 每次调用 Javascript 函数时都会创建一个新对象吗?

javascript - RxJS - future 的插入不可观察?

angular - 是否有管道操作符会在订阅解析之前运行代码?前 : http call

Angular 阻塞(同步)http 调用

javascript - JS函数不响应事件onclick

javascript - 正则表达式功能打破密码强度功能

angular - 组件交互 Angular 2

Angular 7、Ngrx、Rxjs 6 - 在延迟加载的模块之间访问状态

javascript - 半透明线不一致地显示为不透明

javascript - 如何基于选项按钮启用和禁用文本框多个字段