6

我知道一点 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,控制台,输出

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

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

我有一种感觉,我的实现完全脱离了基础,我很感激你能提供的任何帮助。谢谢。

4

2 回答 2

10

你甚至不需要使用两个 Observable 并且只使用一个 with 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

于 2017-01-07T11:39:04.303 回答
4

你不需要心跳,只要有事情发生/变化就发出变化事件:

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

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


// user typing events
const input$ = Rx.Observable
  .fromEvent($('#input'), 'input');

// user stopped typing
const stoppedTypingAfter1s$ = input$
  .switchMapTo(Rx.Observable.timer(1000));

// we merge the streams together
const state$ = Rx.Observable.merge(
    input$.mapTo(1),
    stoppedTypingAfter1s$.mapTo(0)
)
  .startWith(0)
  .do(val => val === 0 ? showIdle() : showTyping())
  .subscribe(console.log);

看住这里

switchMap只要发出新的打字事件, , 就会丢弃任何先前的 1 秒计时器。

于 2017-01-07T11:34:08.073 回答