美文网首页
响应式编程实战—— RxJS 中 if else 的亲戚们

响应式编程实战—— RxJS 中 if else 的亲戚们

作者: du1dume | 来源:发表于2020-06-09 23:00 被阅读0次

    书接上文,我们知道只要打开定时器,控制台就会一直输出内容。现在我们提出个小需求,只有在文本框输入的内容和定时器的值相等时才输出。用 map 操作符当然可以实现,但最佳实践是使用 filter 操作符。

    filter:输入参数为一个条件函数,也就是返回布尔值的函数。意思是对原数据流中的数据进行判断,符合条件的才传递给下面的操作符。

    那我们的需求很容易就可以完成了:

    combineLatest(
      timer$,
      input$,
      (timeValue, inputValue) => ({count: timeValue, input: inputValue})
    )
      .pipe(
      filter(data => data.count === parseInt(data.input)),
      tap(console.log)
    ).subscribe()
    

    比如我们在输入框输入 3 ,再打开定时器,控制台没有任何输出;当定时器到达 3 时,控制台才会输出。

    我们知道当一个流完成时会触发 complete 事件,然而 filter 操作符并不会触发上游数据流的 complete 事件,它只是个阀门,满足它条件的数据才会放过。如果想满足条件后出发上游数据流的 complete 事件,filter 的兄弟 takeWhile 可以帮你完成。

    takeWhile:输入参数和 filter 一样, 为一条件函数,返回布尔值,当接收到的数据满足条件函数才会输出,只要不满足就马上触发上游数据流的 complete 事件。

    实例最能让你体会到这个操作符的行为。代码很简单,就是把 filter 操作符换成 takeWhile 操作符:

    combineLatest(
      timer$,
      input$,
      (timeValue, inputValue) => ({count: timeValue, input: inputValue})
    )
      .pipe(
      takeWhile(data => data.count === parseInt(data.input)),
      tap(console.log)
    )
      .subscribe()
    

    效果图:

    一开始是没有输出的,因为 combineLatest 要等两个流都有值才能输出,定时器有初始值 0 , 文本框没有值。当我们在文本框中输入 0 时,控制台输出了,这是因为 combineLatest 产生的对象满足 takeWhile 的条件函数。但当定时器变为 1 时,马上就停止了。这是因为,combineLatest 产生的第二个值不满足 takeWhile 的条件函数,根据定义,马上触发 combineLatest 的 complete 事件,也就是结束数据流,不再有数据产生。

    我们在 subscribe 函数中加入完整的回调函数,看下是否真的触发了 complete 事件:

    combineLatest(
      timer$,
      input$,
      (timeValue, inputValue) => ({ count: timeValue, input: inputValue })
    )
      .pipe(
      takeWhile(data => data.count === parseInt(data.input)),
      tap(console.log)
    )
      .subscribe(
      _ => console.log("next"),
      e => console.log("error"),
      () => console.log("complete")
    )
    

    效果图:

    如有任何问题,请添加微信公众号“读一读我”。

    相关文章

      网友评论

          本文标题:响应式编程实战—— RxJS 中 if else 的亲戚们

          本文链接:https://www.haomeiwen.com/subject/ylsytktx.html