美文网首页
RxJS入门分享

RxJS入门分享

作者: pengji | 来源:发表于2022-07-11 15:45 被阅读0次

RxJS 实战(入门)分享

Reactive Extensions Library for JavaScript
  1. 📙 什么是RxJS?

Think of RxJS as Lodash for events.

  1. RxJS 是为响应式编程设计的库,它利用 Observables 模式方便我们编写基于异步组合或者回调的代码)

  2. Rx (Reactive extensions) 利用迭代器和观察者模式(观察者模式迭代器模式 ),函数式编程(函数式编程)来优雅的编写和管理事件序列代码的编程思想。

大脑 🧠: 懂了,又没完全懂

Tips: 观察者模式 & 迭代器模式

  1. 观察者模式

  2. 释义:将逻辑分成发布者和观察者。

  3. 发布者:负责产生事件,它会通知所有的注册挂号的观察者。不关心观察者如何处理事件。

  4. 观察者:只负责接收事件并处理自身逻辑,不关心事件如何产生。

  5. 图解:

  1. 迭代器模式

  2. 释义:指的是一个可遍历的对象数据集合的实现。方式有很多,比如数组、链表、树等等迭代器的作用是就是提供一个统一的遍历接口,不需要使用者关心内部的数据集合的实现方式。

  3. 图解:

Tips2:编程范式 - 响应式编程 & 函数式编程

编程范式

  • 命令式编程

  • 声明式编程

  • 事件驱动编程

  • 面向对象(OOP)

  • 函数式编程(FP)

    • 含义:函数式编程是种编程方式,它将电脑运算视为函数的计算。函数编程语言最重要的基础是λ演算(lambda calculus),而且λ演算的函数可以接受函数当作输入(参数)和输出(返回值)。
    • 特征:
      • 函数是"第一等公民"
      • 闭包和高阶函数
      • 惰性计算
      • 递归
      • 没有"副作用"(side effect):指的是函数内部与外部互动(最典型的情况,就是修改全局变量的值),产生运算以外的其他结果。函数式编程强调没有"副作用",意味着函数要保持独立,所有功能就是返回一个新的值,没有其他行为,尤其是不得修改外部变量的值。
  • 响应式编程(RP)

    • 响应式编程(英文:Reactive Programming)是一种面向数据流和变更传播的异步编程范式。
    • 特点:
      • 异步编程:提供了合适的异步编程模型,能够挖掘多核CPU的能力、提高效率、降低延迟和阻塞等。
      • 数据流:基于数据流模型,响应式编程提供一套统一的Stream风格的数据处理接口.
      • 变化传播:简单来说就是以一个数据流为输入,经过一连串操作转化为另一个数据流,然后分发给各个订阅者的过程。
  • 函数式响应式编程(FRP)
    函数式响应式编程(FRP) 是一种编程范式,它采用函数式编程的基础部件(如mapreducefilter等),进行响应式编程异步数据流程编程)。

听到了听到了,两只耳朵都听到了,赶快给我说说RxJS

  1. 🌰 看个栗子

问1: 页面输入框中,如何过滤掉小于3个字符长度的目标值?

/**
 * 常规命令式实现
 */

const input2$ = document.querySelector('.input2');
input2$.addEventListener('input', (event: Event) => {
  const res = (event.target as HTMLInputElement).value;
  if (res.length > 2) {
    console.log(res);
  }
});

import { fromEvent } from 'rxjs';
import { filter, map } from 'rxjs/operators';

/**
 * rxjs 实现
 */

const input$ = fromEvent(document.querySelector('.input1'), 'input');

input$
  .pipe(
    filter(
      (event: InputEvent) => (event.target as HTMLInputElement).value.length > 2
    ),
    map((event: InputEvent) => (event.target as HTMLInputElement).value)
  )
  .subscribe((value: string) => console.log(value));

看起来没有太多优势? 从代码量上来讲,还有可能劣化了?

问2: 上面的输入框每次输入之后都动态保存到后端,如何实现?

/**
 * 常规命令式实现
 */

// 防抖 自己实现 or lodash 之类的方法库
function debounce(fn, delay = 500) {
  let timer = null;

  return function () {
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      fn.apply(this, arguments);
      timer = null;
    }, delay);
  };
}

const input2$ = document.querySelector('.input2');
// 同步
input2$.addEventListener('input', debounce(async (event: Event) => {
    const res = (event.target as HTMLInputElement).value;
    if (res.length > 2) {
      // 异步, 保存数据
      await saveData();
    }
}, 600));

import { fromEvent } from 'rxjs';
import { filter, map, debounceTime, tap } from 'rxjs/operators';

/**
 * rxjs 实现
 */

const input$ = fromEvent(document.querySelector('.input1'), 'input');

input$
  .pipe(
    filter(
      (event: InputEvent) => (event.target as HTMLInputElement).value.length > 2
    ),
    map((event: InputEvent) => (event.target as HTMLInputElement).value),
    debounceTime(600),
    tap(saveData)
  )
  .subscribe();

在线代码: https://stackblitz.com/edit/rxjs-u1sphw?file=index.ts

  1. 🙋 解决什么问题?

使用响应式编程来解决同步/异步混用问题。

最大目的是提供一系列抽象的操作符可以对数据进行转换,而不管这些数据来源是同步或异步的。

  • 输入 - 所有行为转换为流

  • 输出 - 统一使用副作用

  • 流转 - 操作符优雅的时序控制

理解点1:流(streams)

流(streams): 随时间流逝的一系列事件。

举个例子:

image.png

流的概念具体在 rxjs 里面,就是 Observerable 和 Observer 的关系, 如下图所示

  • 它有发送数据的能力(Observerable)

  • 它有接受数据的能力 (Observer,Subscribe)

  • 它能对数据进行转换 (Operator)

image.png
// 创建一个流
// RxJS v6+
import { Observable } from 'rxjs';
/*
  创建在订阅函数中发出 'Hello' 和 'World' 的 observable 。
*/
const hello = new Observable(function(observer) {
  observer.next('Hello');
  observer.next('World');
});

// 输出: 'Hello'...'World'
const subscribe = hello.subscribe(val => console.log(val));

https://stackblitz.com/edit/typescript-baxh98?file=index.ts&devtoolsheight=100

理解点2: Observable & observer & Subscription

  1. 定义

  • Observable (可观察对象): 表示一个一个可调用的未来值或事件的集合。

  • Observer (观察者): 一个回调函数的集合,它知道如何去监听由 Observable 提供的值。

  • Subscription (订阅): 表示 Observable 的执行,主要用于取消 Observable 的执行。

import { Observable } from 'rxjs';

const node = document.querySelector('input');
// input$ 可观察对象 Observable
const input$ = Observable.fromEvent(node, 'input');

/**
* 以下的对象为完整的observer
*   {
    next: (event) => console.log(`You just typed ${event.target.value}!`),
    error: (err) => console.log(`Oops... ${err}`),
    complete: () => console.log(`Complete!`)
    }
*  也可以使用 .subscribe(console) 来简写next的输入  
*/
const subscription = input$.subscribe({
  next: (event) => console.log(`You just typed ${event.target.value}!`),
  error: (err) => console.log(`Oops... ${err}`),
  complete: () => console.log(`Complete!`)
});

// 取消监听
subscription.unsubscribe();
  1. 与Promise对比

由于 Observable 的创建方式和 Promise 有点像,因为用他们做对比学习可能效果更好。

  • 创建流程

  • promise创建流程

image.png

promise 是一次性的,在异步任务执行完毕后,promise 就被标记为 fullfilled 或者 rejected 状态。

  • Observable创建流程

Observable 不是一次性的,在异步任务中可以通过 next 多次触发。只有收到 error 或者 complete,订阅才会结束。

  • 惰性定义

当创建事件发送的逻辑时,所有的逻辑是在订阅后才执行。

import { Observable } from "rxjs";

//创建 promise
const promise = new Promise(resolve => {
  console.log("run promise");
  setTimeout(() => resolve("ok"), 2000);
});

//订阅promise
// promise.then(console.log);

//创建 observable
const observable = new Observable(subscriber => {
  console.log("run observable");
  setTimeout(() => {
    subscriber.next("ok");
    subscriber.complete();
  }, 2000);
});

// observable.subscribe(console.log);
  • 多值

promise是只为单个值设计的,所以当收到一个值之后这个 promise 就结束了。但是 observable不是,只要没有 complete 或者出现 error,它可以发送多个值。

import { Observable } from "rxjs";

//创建 observable
const observable = new Observable(subscriber => {
  let count = 0;
  const id = setInterval(() => {
    subscriber.next(++count);
  }, 1000);

  return () => {
    clearInterval(id);
  };
});

//每间一秒加一
const sub = observable.subscribe(console.log);
//两秒后取消监听,导致事件停止发送
setTimeout(() => sub.unsubscribe(), 2000);

Promise 和 Observable的对比


image.png

理解点3: 操作符 🔗

  • 创建操作符

image.png
  • 过滤操作符

image.png
  • 转换操作符

image.png
  • 组合操作符

image.png
  • 分组操作符

image.png
  • 错误处理操作符

image.png
  • 辅助-条件-数学-配置操作符

image.png
  • 多播操作符

image.png
  • 高阶 Observable 操作符

image.png
  1. 🍽️ 试着做点什么

  2. rxjs 在angular & nestjs 中的应用

nestjs 在源码中大量使用RxJS, 通过流的方式来管理组件间以来的关系。

image.png
  1. axios 重试 https://juejin.cn/post/6933033465126322184

  2. 富交互操作

  3. 游戏

  4. 在线体验:http://acfun-share-demo.web-ops.staging.kuaishou.com/

  5. https://git.corp.kuaishou.com/acfun-frontend/acfun-share-demo/-/tree/master/rxjs

image.png
  1. 埋点

  2. 低码

  3. 😅 最后说点啥

思考:

RxJS被很多人奉为开发中的银弹或者屠龙技,那为什么RxJS没有像 lodash、vue、react等js库一样被广泛传播并且使用呢?

image.png
  1. ✨ 参考书籍 & 资料:

相关文章

  • Rxjs系列教程目录

    RxJS-中文文档RxJS-中文指南 rxjs学习入门心得(一)Observable可观察对象rxjs学习入门心得...

  • Rxjs入门

    本文转自我的博客阅读原文。 概况 Rxjs是响应式编程思想在JS中的一种实现。那么Rxjs到底是个什么东西呢?装逼...

  • RxJS 入门

    RxJS 是什么 Reactive Programming(响应式编程) 是使用异步数据流进行编程的技术,简称 R...

  • 基于 version 6 的 RxJS 入门

    分享几个网站RxJS官网开发手册 RxJS 是什么? 我们可以简单的认为 RxJS 是一套处理异步编程的 API ...

  • RxJS 快速入门

    这是一篇给新手的 RxJS 快速入门,它可能不精确、不全面,但力求对新手友好。 异步与“回调地狱” 我们都知道 J...

  • RxJS简易入门

    什么是RxJS?RxJS解决什么样的问题?通过怎么样的手段?带着这些问题,我们便来学习一下RxJS,本文旨在帮助大...

  • 01RxJS-响应式编程类库

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

  • RxJS

    RxJS官网[https://rxjs.dev/] 1 概述 1.1 什么是 RxJS ? RxJS 是一个用...

  • 浅析Angular之RxJS

    本文结构: 什么是RxJS RxJS有什么特点 RxJS核心概念 什么是RxJS 在javaScript中,我们可...

  • Rxjs入门教程

    该系列教程建立在有一定promise知识的前端同学身上,因为比较抽象,我们在例子中论证说明。eg1. 关键字 Ob...

网友评论

      本文标题:RxJS入门分享

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