首先咱们要弄懂这几个问题:
1.rxjs是什么
2.rxjs能作什么
3.已经有了promise的状况下为何还须要rxjs
4.rxjs的使用方法
若是这些问题都直接去网上搜而后贴上连接,感受我这篇文章就没什么写的必要了。固然了资料已经很是多了,确实不须要我再为你们写一点所谓有帮助的文章了。那么为何还要写呢,写这个是为了本身,为了本身可以更好的理解rxjs,与你们无关,也与白洁无关。javascript
RxJS 是一个库,它经过使用 observable 序列来编写异步和基于事件的程序。它提供了一个核心类型 Observable,附属类型 (Observer、 Schedulers、 Subjects) 和受 [Array#extras] 启发的操做符 (map、filter、reduce、every, 等等),这些数组操做符能够把异步事件做为集合来处理。前端
javascript写前端页面的时候,除了展现数据UI以外,还须要相应用户的操做,展现动态的数据,展现动态的UI。因而前端的异步有:事件(event)、ajax、动画(animation)、定时器(timer)。 处理这些的时候常见的问题有:异步的回调地狱(callback hell) 竞态条件(race condition) 内存泄漏(memory leak) 管理复杂状态(manage complex states) 错误处理(exception handling)java
1.回调地狱:按照普通的javascript方法写,全部的处理写在某个事件的完成后的回调中,当有多个回调依次执行后1->2->3->4很容易将代码写成火箭形,很大一团根本没发改。
2.竞态条件:是指系统出现不恰当的执行时序,而获得不正确的结果。好比搜索框中,每次输入后发送请求获取结果展现在搜索框下面,因为网络或者后端查询的缘由有可能致使最后发送的请求比以前的请求更快的完成了,这时最终展示的并非最后那个请求的结果,而这并非咱们所但愿的。
3.内存泄漏:当单页面应用切换页面时未在合适的时机移除监听事件形成内存泄漏
4.复杂状态的管理:异步带来了状态的改变,可能会使状态管理变得很是复杂,尤为是某个状态有多个来源时,好比有些应用,一开始有一个默认值,再经过 AJAX 获取初始状态,存储在 localStorage,以后经过 WebSocket 获取更新。这时查询状态多是同步或者异步的,状态的变动多是主动获取也多是被动推送的,若是还有各类排序、筛选,状态管理将会更加复杂。
5.错误处理:javascript中的try catch只能捕获同步的错误,对于异步的错误难以获取。promise中可使用一个全局的catch。web
Promise:promise已经解决了不少异步的难点,好比将回调地狱改成了链式调用,统一同步和异步代码,可是promise只有一个结果,而且不能够被提早取消(讲真,多是我作的工做都太简单了,这些问题其实我并无真正遇到过)ajax
异步 API
各类异步的API
DOM Events
XMLHttpRequest
fetch
WebSocket
Service Worker
setTimeout
setInterval
requestAnimationFrame
若是使用rxjs来处理,可使用统一的API,并且借助rxjs各类强大的操做符,能够很是简单的实现需求。对于不一样的场景使用不一样API来完成功能:后端
import { Observable, Subject, asapScheduler, pipe, of, from, interval, merge, fromEvent, SubscriptionLike, PartialObserver } from 'rxjs'; // asapScheduler SubscriptionLike PartialObserver 没有使用过
import { map, filter, scan, take, takeUtil } from 'rxjs/operators';
import { webSocket } from 'rxjs/webSocket';
import { ajax } from 'rxjs/ajax';
建立Observable主要有两步数组
import { Observable } from 'rxjs'; const source$ = new Observable(observer => { let number = 1 setInterval(() => { observer.next(number++) }, 1000) }) const observer = { next : item => console.log(item) } console.log('start') source$.subscribe(observer) console.log('end')
source$.pipe( take(5), // 只要前五个 first(), // 是得到知足判断条件的第一个数据 )
可使用concatMap操做符promise
new Observable((observe) => { setTimeout(() => observe.next(['first']), 1000) }).pipe( concatMap(value => { console.log(value); return new Observable((observe) => { setTimeout(() => observe.next(value.concat('two')), 1000) }) }), ).subscribe()
2.网络
实现相似promise的链式调用
使用concatMap,具体写法相似异步
from(this.getUserInfo()) .pipe( concatMap(userInfo => this.getUserParent(userInfo)), concatMap(parentInfo => this.get(...)) )
3.实现相似promise.all的效果
forkJoin()