javascript - 如何使用 RxJS 显示一个 "user is typing"指标?

标签 javascript rxjs rxjs5 rxjs-dom

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

  1. 当用户输入时,指示符应该立即可见。
  2. 当用户停止打字时,指示器应在用户最后一次打字后 1 秒内仍然可见。

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

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

然后我将它们合并在一起,然后简单地利用结果。如果它是 1,那么我会显示指示器。如果它是 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);

这是 JSBin 的链接:

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

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

  1. 有时,当用户键入时,0 会偷偷溜走,因此指示器会闪烁一瞬间,然后在用户下一次击键时返回。
  2. 不能保证指示器会在用户停止输入 1 秒后消失。只保证指示器会在 1 秒内消失(这与我们想要的有点相反)。
  3. 使用心跳流是正确的 RxJS 方法吗?我觉得可能不是。

我觉得我的实现完全偏离了基础,非常感谢您提供的任何帮助。谢谢。

最佳答案

您甚至不需要使用两个 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());

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

关于javascript - 如何使用 RxJS 显示一个 "user is typing"指标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41520909/

相关文章:

javascript - javascript + angularjs 中的开始和停止时间

javascript - 没有引用句柄的订阅实例是否需要退订?

angular - Rx.ReplaySubject 订阅回调未被调用

rxjs - 如何在rxjs 5中测试使用定时间隔返回可观察值的函数?

javascript - RxJs - 我可以将 BehaviorSubject 与 takeUntil 一起使用吗?

javascript - OpenLayers 3 - map 顶部的 Div 未捕获点击

javascript - 困惑的 Javascript 帖子

javascript - 将参数传递到 Grunt 任务中调用的文件中?

javascript - 在typescript中使用rxjs时出现错误

angular - 从 RXJS 5 迁移到 6 - IntervalObservable