如何使用RxJS显示"用户正在打字"指示?

adr*_*nmc 6 javascript rxjs rxjs5 rxjs-dom

我知道一点BaconJS,但现在我正在尝试通过创建"用户输入..."指示器来学习RxJS.它非常简单,可以用两个简单的规则来解释:

  1. 当用户键入时,指示符应立即可见.
  2. 当用户停止输入时,指示器应该在用户上次键入操作后1秒钟仍然可见.

我不确定这是否正确,但我到目前为止创建了两个流:

  1. 一个心跳流,0每秒发出一次.
  2. 一个流捕获用户键入事件并1为每个事件发出一个.

然后我将它们合并在一起,然后只需点击结果.如果是a 1,那么我会显示指标.如果它是a 0,那么我隐藏指标.

这是看起来像:

const showTyping = () =>
  $('.typing').text('User is typing...');

const showIdle = () =>
  $('.typing').text('');

// 1 second heartbeats are mapped to 0
const heartbeat$ = Rx.Observable
  .interval(1000)
  .mapTo(0);

// user typing events are mapped to 1
const input$ = Rx.Observable
  .fromEvent($('#input'), 'input')
  .mapTo(1);

// we merge the streams together
const state$ = heartbeat$
  .merge(input$)
  .do(val => val === 0 ? showIdle() : showTyping())
  .subscribe(console.log);
Run Code Online (Sandbox Code Playgroud)

这是JSBin的链接:

http://jsbin.com/vekixuv/edit?js,console,output

我对此实现有几个问题和疑问:

  1. 有时当用户打字时,会0偷偷溜过,所以指示灯会在返回下一次用户击键之前闪烁一瞬间.
  2. 在用户停止输入后1秒钟,指示器无法保证消失.它只能保证指标在1秒内消失(这与我们想要的相反).
  3. 使用心跳流正确的RxJS方式来做到这一点?我有一种感觉它可能不是.

我觉得我完全偏离了我的实现,我感谢您提供的任何帮助.谢谢.

mar*_*tin 8

你甚至不需要使用两个Observable并只使用一个debounceTime().您尝试制作的所有逻辑都已存在于debounceTime()运算符中:

const showTyping = () =>
  $('.typing').text('User is typing...');

const showIdle = () =>
  $('.typing').text('');

const input$ = Rx.Observable
  .fromEvent($('#input'), 'input')
  .do(() => showTyping())
  .debounceTime(1000)
  .subscribe(() => showIdle());
Run Code Online (Sandbox Code Playgroud)

查看现场演示:http://jsbin.com/cixipa/6/edit?js,console,output