美文网首页
响应式编程实战——新版RxJS实现真正双击事件流

响应式编程实战——新版RxJS实现真正双击事件流

作者: du1dume | 来源:发表于2020-05-30 06:21 被阅读0次

响应式编程是一种思想,是一种模式,就像 if else 和 for while 一样,是所有编程语言的基本单元。为什么会这样类比?因为现在基本所有的编程语言都有了自己的 Rx 实现,比如 RxJava, Rx.Net, RxJS, RxGo, RxDart等等,至少我们常用的语言都有自己的 Rx。再举个例子,比如斐波那契数列的实现和编程语言无关对么?不同点就是各语言的 if 语句、for 循环语句等等的写法有不同。Rx 也一样,比如我使用 RxJS 实现了按钮的双击操作,我可以把代码拷贝到 Java 中,修改一下操作符的名称,使用方式就好了。

响应式编程同样也是实现组合式编程和积木式编程的最佳实践。使用的越多,你才能体会响应式编程的强大和美妙之处。理论是根基,实战才有价值,下面我们就来看看如何用 RxJS 实现按钮的双击效果。

虽然 DOM 中已经有了双击事件类型,作为练习,让我们假设只有单击事件可以使用。

如果不使用 RxJS 我们将会怎么做?

  1. counter 变量计数
  2. addEventListener 注册单击事件
  3. setTimeout 来判断时间间隔。

让我们看看 RxJS 如何实现。我们知道 Rx 是事件流,单击事件流可以想象成从一根管子,单击事件可以想象成一个珠子,一发生单击事件,这个珠子就从管子的一头流入,从另一头流出。像下面这样:

e----

-e---

--e--

---e-

----e

下面看看怎么用 RxJS 实现这根管子:

如何使用单击事件流实现双击事件流呢?管子好说,关键是里面的珠子。这里要用到 4 个 RxJS 操作符。先简要说下操作符。我觉得操作符可以类比为中间件,拦截函数等等,后台同学好理解,前台同学不理解的话可以去看看 koa 框架。操作符接收一根管子,监控管子里的珠子并做完操作,然后重新生成一根管子,里面存放操作完的珠子。

throttleTime:throttle 的中文翻译是节流阀的意思。它的参数是一段时间。它的作用在时间参数范围内的珠子可以过,时间一到阀门就关上了,谁也过不去了。当第一个珠子经过它时,它就开始计时。

buffer:它的参数是一个事件流或者说管子。它的作用是收集这根管子流出的珠子,放进一个袋子里,这个袋子就是数组。

map:对经过它的珠子做处理。

filter:对经过它的珠子做过滤,满足要求的珠子才能过去。

下面是实现:

import React, { useRef, useEffect } from "react";

import { fromEvent } from "rxjs";
import { buffer, filter, map, throttleTime } from "rxjs/operators";

// throttleTime 操作符的第二个参数,其实默认值也是 async,那为什么还要传入呢?因为假如你有三个参数,传入了第一个和第三个,第二个就必须传了,js 无法忽略中间的参数不填。
import { async } from "rxjs/internal/scheduler/async"; 

export default function App() {
  const btnRef = useRef(null);

  // 这个是 throttleTime 操作符的第三个参数,默认值 leading 为 true,trailing 为 false。
  const throttleConfig = {
    leading: false,
    trailing: true
  }

  useEffect(() => {
    const btnClick$ = fromEvent(btnRef.current, "click");
    
    const throttled$ = btnClick$.pipe(throttleTime(250, async ,throttleConfig))

    const btnDblClick$ = btnClick$.pipe(
      buffer(throttled$),
      map(arr => arr.length),
      filter(len => len === 2),
    );

    const subscription = btnDblClick$.subscribe(() => {
      console.log("双击啦");
    });
    return () => {
      subscription.unsubscribe();
    };
  });

  return (
    <div className="App">
      <button ref={btnRef}>我是一个按钮</button>
    </div>
  );
}

解释说明:

  1. 快速地在按钮上点击两次,将产生两个珠子,也就是 btnClick$ 事件流里面有两个 click 事件。
  2. 我们把这根管子交给了 buffer 操作符,然而 buffer 对这根管子不感兴趣,它需要另外一个管子;这另外一根管子也是基于单击事件流生成的,只不过加了个阀门,里面有个定时器,当你第一次 click 的时候,定时器开始计时,计时期间的 click 事件都可以进到管子里;当定时器停止时,click 事件将无法进到管子里。定时器归零,直到你又一次 click 再开始计时。
  3. 我们把上一步的管子交给了 buffer,buffer 把这根管子里的珠子放进袋子,也就是数组中。比如交给 buffer 之前的管子里有两个珠子,交给 buffer 之后,buffer 把这俩数字放进了袋子,放进了一根新管子。
  4. 这一步 map 操作符拿到了管子,它算出袋子里的珠子数量,放到另一根新管子里,新管子里放的就是珠子的数量。
  5. filter 操作符拿到前面传过来的管子,它对里面的数字有意见,不等于 2 的都扔了,把等于 2 的放进了另一根管子,传递下去。
  6. 这一步没有操作符了,因此 filter 返回的管子给了 btnDblClick$ 变量保存。

综上,只要 btnDlbClick$ 流出的事件,就是双击事件,明白了吗?不明白请关注微信公众号“读一读我”哦。

相关文章

  • 响应式编程实战——新版RxJS实现真正双击事件流

    响应式编程是一种思想,是一种模式,就像 if else 和 for while 一样,是所有编程语言的基本单元。为...

  • 响应式编程实战——RxJS 重构组合事件流

    今天我们来看看如何改变事件发生的频率。让我们添加两个按钮,分别代表了二分之一秒产生一个事件的事件流和四分之一秒产生...

  • 响应式编程实战—— RxJS 改变事件流与合并事件流

    今天我们来优化一下之前的程序。在 scan 中我们以匿名函数的形式对一个对象的属性了进行了加 1 操作,我们可以把...

  • 介绍RxJS在Angular中的应用

    RxJS是一种针对异步数据流编程工具,或者叫响应式扩展编程;可不管如何解释RxJS其目标就是异步编程,Angula...

  • 01RxJS-响应式编程类库

    rxjs-响应式编程类库)RxJS官网[https://rxjs.dev/] RxJS(Reactive Exte...

  • RxJava

    响应式编程概述 什么是响应式编程? 是一种基于异步数据流概述的编程模式 响应式编程--关键概念 事件 响应式编程-...

  • Rxjs

    响应式编程简介 Rxjs概念 Rxjs全称Reactive Extension for JavaScript,Ja...

  • 第1章 函数响应式编程

    注: 学习程墨老师《深入浅出RxJS》的笔记 RxJS采用了函数响应式编程。RxJS世界中有一种特殊的对象,称为流...

  • RxSwift分享1

    什么是响应式编程 响应式编程是一种和事件流有关的编程模式,关注导致状态值改变的行为事件,一系列事件组成了事件流。 ...

  • 响应式编程

    响应式编程 可观察对象Angular集成了 参考:Rxjs,它使用 Observable 对象来创建流,主要是用于...

网友评论

      本文标题:响应式编程实战——新版RxJS实现真正双击事件流

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