zoukankan      html  css  js  c++  java
  • rxjs入门指南

    使用场景

    1. 在复杂的,频繁的异步请求场景,使用rxjs。
    2. 在依赖的多个异步数据,决定渲染的情景,使用rxjs。

    总之:在前台频繁的、大量的、和后台数据交互的复杂项目里面,使用rxjs(web端,iOS,android端等,客户端都可考虑使用)

    rxjs初步认识

    1. 数据和数据观察者的绑定。数据变化,观察者动作——监听或者观察者模式。
    2. 观察者的迭代执行动作——观察者注册任意个异步或同步动作,迭代执行。

    hello world

    let start = Rx.Observable.create((observer) => {
        observer.next('hello world')
    });
    start.subscribe((a) => {
        console.log(a)
    })
    
    # >>>
    hello world
    
    

    核心对象(概念)

    1. Observable 可观察对象
      数据,动作等进行包装后,变成observable可观察对象,供observer观察者监听

    2. Observer 观察者
      一些列的回调函数,用来应对Observable的变化。

    3. Subscription (订阅)
      将可观察对象和观察者建立起关系。

    4. Operator(操作符)
      库提供的方法,强大。就像js数组提供了map、filter、reduce等方法一样。

    5. subject(主体)
      subject像是维护着一个监听者的注册表。
      当有新的事件发生时,广播给各个监听者。

    6. Schedulers (调度器)
      先不管,目前没用到,也不影响使用

    基本示例

    1

    let firstObservable = Rx.of('one', 'two');
    firstObservable.subscribe((a) => {
        console.log(a)
    })
    
    firstObservable.subscribe((a) => {
        console.log(a+'-222')
    })
    
    # >>>
    one
    two
    one-222
    two-222
    
    

    2

    let secondObservable = Rx.Observable.create((data) => {
        let a = 0;
        //模拟异步请求
        setInterval(() => {
            data.next(a)
            a += 1
        }, 1000)
    });
    console.log('just before subscribe');
    secondObservable.subscribe((a) => {
        console.log(a + '11')
    });
    secondObservable.subscribe({
        next: x => console.log('got value ' + x),
        error: err => console.error('something wrong occurred: ' + err),
        complete: () => console.log('done'),
    });
    console.log('just after subscribe');
    
    # >>>
    just before subscribe
    just after subscribe
    011
    got value 0
    111
    got value 1
    211
    got value 2
    311
    got value 3
    ...
    
    

    3, subject

    let firstObservable = Rx.of('one', 'two');
    firstObservable.subscribe((a) => {
        console.log(a)
    });
    firstObservable.subscribe((a) => {
        console.log(a+'-222')
    })
    
    
    
    var subject = new Rx.Subject();
    
    subject.subscribe({
        next: (v) => console.log('observerA: ' + v)
    });
    subject.subscribe({
        next: (v) => console.log('observerB: ' + v)
    });
    
    subject.next(1);
    subject.next(2);
    
    #>>>
    
    one
    two
    one-222
    two-222
    observerA: 1
    observerB: 1
    observerA: 2
    observerB: 2
    

    状态控制

    监听input输入框得变化,控制处理动作的流动或者规则

        var input = Rx.Observable.fromEvent(document.querySelector('input'), 'input');
    
        // 过滤掉小于3个字符长度的目标值
        input.filter(event => event.target.value.length > 2)
            .map(event => event.target.value)
            .subscribe(value => console.log(value)); 
    
        //延迟200毫秒
        input.delay(200)
            .map(event => event.target.value)
            .subscribe(value => console.log(value));
        
        //一秒内触发一次
        input.throttleTime(1000)
            .map(event => event.target.value)
            .subscribe(value => console.log('一秒内触发一次-throttleTime' + value)); 
    
        // 停止输入后200ms方能通过最新的那个事件
        input.debounceTime(1000)
            .map(event => event.target.value)
            .subscribe(value => console.log('停止输入1000毫秒后-debounceTime' + value)); 
        
        //处理三次后停止
        input.take(3)
            .map(event => event.target.value)
            .subscribe(value => console.log('3次事件后停止流' + value)); 
    
        // 直到其他 observable 触发事件才停止事件流
        var stopStream = Rx.Observable.fromEvent(document.querySelector('button'), 'click');
        input.takeUntil(stopStream)
            .map(event => event.target.value)
            .subscribe(value => console.log('button' + value)); // "hello" (点击才能看到)
    
    

    产生值

    
    //输入 hello world
    
     var input = Rx.Observable.fromEvent(document.querySelector('input'), 'input');
    
        // 传递一个新的值
        input.map(event => event.target.value)
            .subscribe(value => console.log('map'+value));
    
        // 通过提取属性传递一个新的值---将对象的一个值提取出来
        input.pluck('target', 'value')
            .subscribe(value => console.log('pluck'+value));
    
        // 传递之前的两个值
        input.pluck('target', 'value').pairwise()
            .subscribe(value => console.log('pluck/pairwise'+value)); // ["h", "he"]
    
        // 只会通过唯一的值--一次输出一个且历史上重复输入,不会输出。
        input.pluck('data').distinct()
            .subscribe(value => console.log('distinct'+value)); // "helo wrd"
    
        // 不会传递重复的值,上一个和当前值
        input.pluck('data').distinctUntilChanged()
            .subscribe(value => console.log('distinctUntilChanged'+value)); // "helo world"
    

    应用状态的保持

    rxjs使用的是纯函数。但是应用是有状态的,可以使用scan来累计状态

        var button = document.querySelector('button');
        Rx.Observable.fromEvent(button, 'click')
        // 对流进行 scan (reduce) 操作,以获取 count 的值
            .scan(count => count + 1, 0)
            // 每次改变时都在元素上设置 count
            .subscribe(count => document.querySelector('#count').innerHTML = count);
    
        //使用merge将多个observables 合并在一起,监听处理
        var increaseButton = document.querySelector('#increase');
        var increase = Rx.Observable.fromEvent(increaseButton, 'click')
        // 我们再一次映射到一个函数,它会增加 count
            .map(() => state => Object.assign({}, state, {count: state.count + 1}));
    
        var decreaseButton = document.querySelector('#decrease');
        var decrease = Rx.Observable.fromEvent(decreaseButton, 'click')
        // 我们还是映射到一个函数,它会减少 count 
            .map(() => state => Object.assign({}, state, {count: state.count - 1}));
    
        var inputElement = document.querySelector('#input');
        var input = Rx.Observable.fromEvent(inputElement, 'keypress')
        // 我们还将按键事件映射成一个函数,它会产生一个叫做 inputValue 状态
            .map(event => state => Object.assign({}, state, {inputValue: event.target.value}));
    
        // 我们将这三个改变状态的 observables 进行合并
        var state = Rx.Observable.merge(
            increase,
            decrease,
            input
        ).scan((state, changeFn) => changeFn(state), {
            count: 0,
            inputValue: ''
        });
    
        // 我们订阅状态的变化并更新 DOM
        state.subscribe((state) => {
            document.querySelector('#count').innerHTML = state.count;
            document.querySelector('#hello').innerHTML = 'Hello ' + state.inputValue;
        });
    
  • 相关阅读:
    关于FPS游戏痕的问题
    移动端输入框获取焦点后,虚拟键盘弹起,把固定的底部也顶起来了
    正则匹配移动端
    js 判断对象是否为空
    jsonp跨域原理解析
    Webstorm的一些常用快捷键
    webstorm创建js文件时自动生成js注释
    帮你彻底搞懂JS中的prototype、__proto__与constructor(图解)
    this指北 (一篇读懂)
    原型链
  • 原文地址:https://www.cnblogs.com/panfengde/p/10132539.html
Copyright © 2011-2022 走看看