RxJS 之于异步,就像 JQuery 之于 dom

发表于 2年以前  | 总阅读数:414 次

记得当年我刚学 JavaScript 的时候,是从原生的 dom api 学起的,用原生的 dom api 完成一些增删改的功能,之后就会学习 JQuery。

刚接触 JQuery 的时候,感觉这也太爽了吧。比如这样一段逻辑:

创建一个 p 标签包含一个文本节点,然后插入到 container 中。

用原生 dom api 写是这样的:

const containerDom = document.getElementById('container');

const textDom = document.createTextNode("Hello World.");
const paraDom = document.createElement("p");
paraDom.appendChild(textDom);

containerDom.appendChild(paraDom);

而用 JQuery 写是这样的:

const $container = $('#container');

$container.append('<p>Hello World.</p>');

比起用原生 dom api 来写简化太多了!这也是为什么 JQuery 当年那么火的原因。

虽然现在都用 Vue、React 这种数据驱动的前端框架来写页面,基本不直接操作 dom 了。但涉及到一些活动页等需要直接操作 dom 的场景,用 JQuery 依然很方便。

那 JQuery 做了什么呢?

JQuery 把 dom 封装了一层,提供了很多操作 dom 的 api,并且支持链式调用,可以方便的组织 dom 操作逻辑,而且还支持插件来自定义一些方法在链式调用中使用。

可能你会说,JQuery 不是基本用不到了么,提它干什么?

因为我觉得 JQuery 对 dom 操作的这层封装很好,把操作 dom 的复杂度降低了很多。前端除了经常操作 dom 外,还会经常处理异步,比如 XHR 和 Fetch、Event Listener 等,虽然可以用 Promise 封装,还可以进一步简化成 async/await 的写法,但是 Promise 和 async/await 只是改变了异步逻辑的书写形式,并没有降低异步逻辑编写的复杂度。 能不能就像 JQuery 对 dom 操作的封装那样,把异步逻辑也给封装一层,简化下异步逻辑的编写呢?

确实有这样的一个库,就是 Rx.js。

写 JQuery 的时候我们是把 dom 封装了一层,比如 const $container = $(dom),这样就能用 JQuery 内置的工具函数或者通过插件扩展的一些函数,通过链式调用把逻辑串起来。

为了和 dom 对象容易区分,我们会把 JQuery 对象命名成 $、$yy 等。

那么 Rx.js 第一步要做的也是把异步逻辑包一层:

也就是把 Event Listener、Promise、回调函数这种异步代码包一层:

// 包一层 Event Listener
const observable$ = Rx.Observable.fromEvent(document.querySelector('button'), 'click'); 

// 包一层 Promise
const observable2$ = Rx.Observable.fromPromise(fetch('/users'));

// 包一层 callback
const observeable3$ = Rx.Observable.bindCallback(fs.exists);

包装以后的对象不叫 RxJS 对象,叫做 Observable 对象,而且为了便于区分,我们会把它命名为 xxx$、$,就像 JQuery 对象我们会命名成 $、$yyy 一样。

然后就可以用内置的一系列工具函数了,这些叫做操作符 operator:

observable$.pipe(
    throttleTime(300),
    take(3),
    map(event => event.target.value)
);

比如异步逻辑我们经常做节流处理,那就不用自己写了,直接用内置的操作符 throttleTime 就行。

还有忽略前三次事件 take(3),对数据做一次映射 map(() => xxx) 等等这些常见异步逻辑用操作符来写就很简单。

把异步逻辑组织成链条(或者叫管道 pipe),用操作符来写每步的处理逻辑,然后串联起来,这样就把异步逻辑的书写变为了 pipe 的组织。而且就像 JQuery 可以写插件来扩展一样,Rxjs 也支持自定义操作符。

经过这个管道之后,数据经过了每一步异步逻辑的处理,我们可以通过 subcribe 监听,拿到最终的数据。

observerable$.subscribe((value) => {
    // xxx
})

当然,也可能在处理的过程中出错了,那也要把 error 传下去,并且最终处理完以后也会有个通知,所以可以写这样三种情况的处理:

observerable$.subscribe({
    next: (v) => {},
    error: (err) =>{},
    complete: () => {}
});

这些处理逻辑叫做 Observer。

这就是 RxJs 做的事情了。因为异步逻辑是对某个事件的响应,这也叫做响应式编程

刚才我们创建 Observable 是包了一层 Event Listener、callback、Promise,当然也可以直接创建这样一个 Observable 对象:

比如我们把一系列数封装成 Observable:

// 多个数据
const observable$ = Rx.Observable.of(1, 2, 3); 

// 数组中的多个数据
const observable2$ = Rx.Observable.from([1,2,3]);

或者经过一些逻辑逻辑产生一系列数据:

var observable$ = new Rx.Observable(function (observer) {
    observer.next(1);
    observer.next(2);
    observer.next(3);
    setTimeout(() => {
        observer.next(4);
        observer.complete();
    }, 1000);
});

或者这样:

const observable$ = new Rx.Subject();

observable$.next(1);
observable$.next(2);

这里的区别是 Subject 是可以在外部调用 next 来产生数据的,而 new Observable 是在回调函数内调用 next 产生数据。

我们小结一下:

就像 JQuery 对 dom 包了一层,然后提供了简化 dom 操作的 api 一样,RxJS 也对异步逻辑包装了一层,然后提供了一系列 operator。我们可以把 EventListenr、Promise、callback 等包装成 Observable(或者自己用 of、from、Subject 等创建 Observable),然后用内置的或者自己扩展的 oprator 组织处理管道,在管道的末尾用 Observer 接受数据、处理错误。这样就把异步逻辑的编写,转变为了操作符管道的组织。当对内置的 operator 足够熟练或者自己沉淀了一些 operator 之后,写异步的逻辑速度会变得很快。

因为 RxJS 只是对异步逻辑的封装,和 Vue、React 等前端框架并不冲突,所以可以很好的结合在一起。(Angular 甚至默认就集成了 RxJS)

比如在 Vue 里面,我们可以把事件用 Subject 封装成一个 Observable,然后就可以用 RxJS 的操作符来组织异步逻辑了:

<div @click="clickHandler">点我</div>
import { Subject } from 'rxjs'
import { debounceTime } from 'rxjs/operators'

export default {
   data() {
     return {
       observable$: new Subject()
     }
   },
   created() {
      this.observable$.pipe(debounceTime(500)).subscribe((event) => {
        // xxx
      })
   },
   methods: {
      clickHandler(event) {
         this.observable$.next(event)
      }
   }
}

在 React 里面也一样,用 Subject 自己创建个 Observale,就可以把异步逻辑的编写转变为 operator 的组装了:

class MyButton extends React.Component {
    constructor(props) {
       super(props);
       this.state = { count: 0 };

       this.observable$ = new Rx.Subject();

       this.observable$.pipe(
           debounceTime(500),
           map(() => 1),
           scan((total, num) => total + num, 0)
       );

       this.observable$.subscribe(x => {
          this.setState({ count: x })
       })
    }
    render() {
        return <button onClick={event => this.observable$.next(event)}>{
            this.state.count
        }</button>
    }
}

我们用 Subject 创建了个 Observable 对象,每次点击都调用 next 产生一个数据,传入处理管道。

管道我们是用 operator 组织的,先做了 500ms 的截流,然后把值变为 1,之后计数。

处理完之后传递给 Observer 的就是累加后的数值,设置到 state 即可。

这样一段节流 + 计数的异步逻辑就写完了,其实就是组装了下 operator,这就是 RxJS 的意义。

总结

用原生的 dom api 进行 dom 操作比较繁琐,所以我们会使用 JQuery,它把 dom 包了一层,提供了很多方便的内置 api,而且还支持通过插件扩展,这样极大的简化了 dom 操作。

除了操作 dom,前端开发还经常要写异步逻辑,同样也需要这样一个包一层的库来简化,它就是 Rx.js。

Rx.js 把 Event Listener、Promise、callback 等封装成了 Observable(也可以自己创建),提供了很多操作符 operator(还可以自定义),用它们来组装成处理管道(pipe)来处理异步逻辑,最后传入 Observer 来接收数据和处理错误。这样把异步逻辑的编写转变为了 operator 的组装,把填空题变为了选择题,异步逻辑的编写速度和体验自然会提升很多。

而且,RxJS 是专门处理异步逻辑的,可以和前端框架很好的结合在一起使用。

就像用 JQuery 操作 dom 很爽一样,熟悉了 RxJS 的 operator,用 RxJS 编写(组装)异步逻辑的体验也非常棒。

本文由哈喽比特于2年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/S7qVcxBUE2PXB43Hl6ZFLg

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:1年以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:1年以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:1年以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:1年以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:1年以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:1年以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:1年以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:1年以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:1年以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:1年以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:1年以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:1年以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:1年以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:1年以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:1年以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:1年以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:1年以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:1年以前  |  398次阅读  |  详细内容 »
 相关文章
Android插件化方案 5年以前  |  237271次阅读
vscode超好用的代码书签插件Bookmarks 2年以前  |  8108次阅读
 目录