一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天, 点击查看活动详情 。
上一篇文章中,我们综合了之前学习过的辅助方法和操作符,完成了一个拖拽元素的小案例,实现的难度不大,主要是需要对之前一些 RxJS 方法能够有一定的了解。
那么接下来我们要来一起实现一个更加贴切我们日常开发的实际案例-- 获取文章 ,向后端获取数据应该是前端每天都需要上手的一件事情,平常我们可能都是使用封装好的放来来获取文章,然后对返回的 promise 进行各种操作,那么本篇文章当中,我们就来看一下,如果是使用 RxJS,我们要怎么来发送请求获取服务端的数据。
因为本文没有后端的一个支持,所以只是简单地使用 Promise 加上 定时器来模拟后端的一个请求。
这里我初始化了一个文章类,并且内部存放了部分的文章数据,拥有一个获取方法会根据传入的标题在延时一秒之后返回对应的文章。
class Article {
constructor() {
this.arr = [
{ title: "1", data: "data1" },
{ title: "2", data: "data2" },
{ title: "3", data: "data3" },
getData(title) {
return new Promise((resolve, reject) => {
this.arr.forEach((e) => {
if (e.title == title) {
setTimeout(() => {
resolve(e);
}, 1000);
RxJS 获取文章
监听键盘事件
首先我们需要在页面中新建一个搜索框用于搜索文章,并且在事件中存在一个 'keyup'
事件可以捕获到键盘的输入:
并且在 target
底下存在着 value
保存着当前输入框的值:
模拟请求发送
既然我们可以获取到键盘当前的输入,那么就可以根据当前的数据去发送请求来获取对应的文章,获取当前的数据应该使用 map
方法来做一个转化,然后用 switchMap
传入经过 from
方法转化的 getData
方法, getData
方法会返回一个 promise,但是经过 from
的转化,我们最终就可以通过订阅获取到输出的数据。
import { fromEvent, from } from "rxjs";
import { map, switchMap } from "rxjs/operators";
const article = new Article();
const search = document.getElementById("search");
fromEvent(search, "keyup")
.pipe(
map((event) => event.target.value),
switchMap((keyword) =>
from(article.getData(keyword)).pipe(map((response) => response.data))
.subscribe((e) => console.log(e));
这是通过 promise 来模拟请求的情况,正常情况下请求方法返回的也是promise,也可以通过 from
方法来进行转化。
请求防抖以及去重
上面的模拟请求当中,我们来遗漏了一个前端很重要的两个点,键盘事件的防抖以及去重。
防抖:当用户多次的进行输入的时候,不需要进行响应,只有当停止输入之后才会触发事件
这里不难理解,每一次按下按键都会触发请求的话,那么如果输入一串字符串,将会触发非常多次的请求。
所以我们需要给键盘点击方法加上防抖,只有当用户停止输入后,才会去触发事件。
这里我们就需要用到 debounceTime
这个操作符来进行一个防抖操作。
在 pipe 中加上
debounceTime(700)
去重,如果下一次的输入和上一次是相同的,那么结果也应该是相同的,就不需要发送请求。
假如用户很快地删除掉上一次的输入,然后又再次输入一样的数据,这时候发出请求的数据是相同的,那么响应的数据就也是相同的,就完全不需要做出一个事件的发送。
所以我们需要给键盘点击方法加上去重,如果本次输入和上一次一样,就不会发送请求。
这里我们就需要用到 distinctUntilChanged
这个方法来进行去重。
在 pipe 中加上
distinctUntilChanged(),
要注意的是,这个去重操作的判断要添加在 map 操作符之后,因为每次点击事件的输入的对象都是不同的,但是我们要判断的是用户输入的值,使用需要将去重检测放在 map 操作符的后面。
import { fromEvent, from } from "rxjs";
import { map, switchMap, debounceTime } from "rxjs/operators";
const article = new Article();
const search = document.getElementById("search");
fromEvent(search, "keyup")
.pipe(
debounceTime(700),
map((event) => event.target.value),
switchMap((keyword) => {
console.log("我触发了");
return from(article.getData(keyword));
.subscribe((e) => console.log(e));
到这里,我们就基本上完成了一个简单的利用 RxJS 实现的请求模拟。
本文我们举了平常业务中比较经常接触到的一个获取请求来进行模拟,利用 RxJS 代替平时的方法发送请求,这样才能够比较好的体会到,使用 RxJS 和正常语法有着什么样的不同,RxJS 给我们带来了什么。