写点什么

RxJS 实现“搜索”功能

作者:掘金安东尼
  • 2022 年 8 月 14 日
    中国台湾
  • 本文字数:1767 字

    阅读完需:约 6 分钟

闲言少叙,直接开冲!


先用 JS 原生写一个搜索功能:


<input id="text"></input><script>    var text = document.querySelector('#text');    text.addEventListener('keyup', (e) =>{        var searchText = e.target.value;        $.ajax({ // 发送请求            url: `search.qq.com/${searchText}`,            success: data => {              render(data); // 处理数据            }        });    });</script>
复制代码


搜索都是要做防抖处理的,简易版防抖如下:


<input id="text"></input><script>    var text = document.querySelector('#text'),        timer = null;    text.addEventListener('keyup', (e) =>{        clearTimeout(timer); // 频繁触发则会清除上一定时器        timer = setTimeout(() => {            console.log('发起请求..');        },300) // 300 后毫秒触发;    })</script>
复制代码


所以,搜索功能演变为:


<input id="text"></input><script>    var text = document.querySelector('#text'),        timer = null,        currentSearch = '';     text.addEventListener('keyup', (e) =>{        clearTimeout(timer)        timer = setTimeout(() => {            var searchText = e.target.value;            $.ajax({                url: `search.qq.com/${searchText}`,                success: data => {                    render(data);                }                       });        },300)    })</script>
复制代码


对吧,很常规。但是实际上的业务往往会远大于示例中的代码,按照上面的思路,最终会写成这种玩意儿:



一点不夸张。


这个时候,只能献祭出终极解决方案:本篇主角 —— RxJS 了,其实不止有 JS 的 RxJS,与之对应的还有,RxJava、RxAndroid、RxSwift,它们都是处理异步编程的【核武器库】;


RxJS 实现:


import { fromEvent } from 'rxjs';import { debounceTime, pluck, switchMap } from 'rxjs/operators';
var text = document.querySelector('#text');var inputStream = Rx.Observable.fromEvent(text, 'keyup') .debounceTime(300) .pluck('target', 'value') .switchMap(url => Http.get(url)) .subscribe(data => render(data));
复制代码


让我们来一一解析它的 API:


  • fromEvent


fromEvent 用于将事件转换成 observable 序列(若还不理解什么是 observable 的同学,可以简单理解它为一个加强版本的 Promise);


总之,创建点击时间的 observable 都这样写:


const source = fromEvent(document, 'click');


  • debounceTime


这个好理解,对事件加防抖的,参数就是防抖时间;


官方解释就是:舍弃掉在两次输出之间小于指定时间的发出值;


u1s1,这解释读起来很费劲。。(若还不理解什么是防抖的同学,可以将它理解为 LOL 中的回程,按下 B 键,隔了几秒,才会真正回城回血,如果一直按 B ,则一直不会回城);


  • pluck


选择属性来发出;


比如:


const source = from([{ name: 'Joe', age: 30 }, { name: 'Sarah', age: 35 }]);// 提取 name 属性const example = source.pipe(pluck('name'));// 输出: "Joe", "Sarah"const subscribe = example.subscribe(val => console.log(val));
复制代码


在搜索的例子中,则是提取点击的 event.target.value


  • switchMap


switchMap 要重点理解下;


官方解释是:映射成 observable,完成前一个内部 observable,发出值。


没错,依然不好懂 ZZZ


不如,换个角度来解释:


RxJS 中通常用【弹珠图】来表示“事件流”,比如 map api 的弹珠图如下:



switch api 的弹珠图如下:



当发出一个新的内部 Observable 时, switch 会从先前发送的内部 Observable 那取消订阅,然后订阅新的内部 Observable 并开始发出它的值。


即永远订阅最新的 Observable;


那么:switchMap = map + switch ,示意如下:



结合理解,在本篇搜索示例中,即用 Http.get(url) 所得 data 值作为事件流的最新值,进行后续的传递;


至此,我们可以得出:RxJS 让代码变得十分简洁、可读,前提是,我们熟悉事件流这个东西,熟悉它的 API~~




OK,以上便是本篇分享,希望对你能有所帮助~觉得不错,给个三连吧 👍👍👍


我是掘金安东尼,输出暴露输入,技术洞见生活。

发布于: 刚刚阅读数: 3
用户头像

安东尼陪你度过漫长编程岁月~ 2022.07.14 加入

社会我瓜哥,人狠话不多😎 微信 anthony1453,加我交个朋友😎 正联合【机械工业出版社】出版《程序员成长手册》,敬请期待😎 真正的大师,永远怀着一颗学徒的心(易)😎

评论

发布
暂无评论
RxJS实现“搜索”功能_前端_掘金安东尼_InfoQ写作社区