Commit 363c56d6 by zerozou

Add 2017/8/30 log:RxJS

parent 57e7604b
# 2017/8/30
## RxJS
* Subject
Subject是一种特殊的Observable,Subject允许将值多播给多个观察者,而Observable是单播的(每个已订阅的观察者都拥有Observable的独立执行)
**每个Subject都是Observable** 对于Subject,可以提供一个观察者并执行 `subscribe` 方法,就可以正常接收值。对于观察者,无法判断是普通的Observable还是Subject。而Subject的`subscribe`方法不会调用发送值的新执行,而是类似于`addEventListener`一样,将给定的观察者注册到观察者列表中
**每个Subject都是观察者** 它有 `next``error``complete` 方法,调用`next`方法就会将值多播给已注册监听该Subject的观察者们
```javascript
let subject = new Rx.Subject()
subject.subscribe({
next: val => console.log(`Observer1: ${val}`)
})
subject.subscribe({
next: val => console.log(`Observer2: ${val}`)
})
subject.next(1)
subject.next(2)
/*
* Observer1: 1
* Observer2: 1
* Observer1: 2
* Observer2: 2
*/
```
由于Subject是观察者,所以可以将其作为参数传递给任意Observable的`subscribe`方法
```javascript
let subject = new Rx.Subject()
subject.subscribe({
next: val => console.log(`Observer1: ${val}`)
})
subject.subscribe({
next: val => console.log(`Observer2: ${val}`)
})
let observable = Rx.Observerble.from([1, 2])
observable.subscribe(subject)
/*
* Observer1: 1
* Observer2: 1
* Observer1: 2
* Observer2: 2
*/
```
* BehaviorSubject
它保存了发送给消费者的最新值,并在有新的观察者订阅时会立即从BehaviorSubject接收到最新值
```javascript
let suject = new Rx.BehaviorSubject(0) // 0是初始值
subject.subscribe({
next: val => console.log(`Observer1: ${val}`)
})
subject.next(1)
subject.next(2)
subject.subscribe({
next: val => console.log(`Observer2: ${val}`)
})
subject.next(3)
/*
* Observer1: 0
* Observer1: 1
* Observer1: 2
* Observer2: 2
* Observer1: 3
* Observer2: 3
*/
```
* ReplaySubject
ReplaySubject记录Observable执行中的多个值并将其回放给新的订阅者
```javascript
let subject = new Rx.ReplaySubject(3) // 设置回放三个值
subject.subscribe({
next: val => console.log(`Observer1: ${val}`)
})
subject.next(1)
subject.next(2)
subject.next(3)
subject.next(4)
subject.subscribe({
next: val => console.log(`Observer2: ${val}`)
})
subject.next(5)
/*
* Observer1: 1
* Observer1: 2
* Observer1: 3
* Observer1: 4
* Observer2: 2
* Observer2: 3
* Observer2: 4
* Observer1: 5
* Observer2: 5
*/
```
除了设置回放值,还可以设置windowTime(单位:ms)来确定多久前的值可以被回放
```javascript
let subject = new Rx.ReplaySubject(100, 500)
subject.subscribe({
next: val => console.log(`Observer1: ${val}`)
})
let i = 1
setInterval(() => subject.next(i++), 200)
setTimeout(() => {
subject.subscribe({
next: val => console.log(`Observer2: ${val}`)
})
}, 1000)
/*
* observer1: 1
* observer1: 2
* observer1: 3
* observer1: 4
* observer1: 5
* observer2: 3
* observer2: 4
* observer2: 5
* observer1: 6
* observer2: 6
* ...
*/
// 3,4,5是在新的订阅者发生前500ms
```
* AsyncSubject
只有当执行完complete,才会将执行的最后一个值发送给观察者
```javascript
let subject = new Rx.AsyncSubject()
subject.subscribe({
next: val => console.log(`Observer1: ${val}`)
})
subject.next(1)
subject.next(2)
subject.next(3)
subject.subscribe({
next: val => console.log(`Observer2: ${val}`)
})
subject.next(4)
subject.complete()
/*
* Observer1: 4
* Observer2; 4
*/
```
* Operator
操作符是Observable类型上的方法,当操作符被调用时,不会改变已存在的Observable,而是返回一个新的Observable,它的subscription的逻辑是基于第一个Observable的.
[操作符分类介绍](http://cn.rx.js.org/manual/overview.html#h213)
* Scheduler
调度器控制何时启动subscription和何时发送通知
**调度器是一种数据结构**。 它知道如何根据优先级或其他标准来存储任务和将任务进行排序。
**调度器是执行上下文**。 它表示在何时何地执行任务(举例来说,立即的,或另一种回调函数机制(比如 setTimeout 或 process.nextTick),或动画帧)。
**调度器有一个(虚拟的)时钟**。 调度器功能通过它的 getter 方法 now() 提供了“时间”的概念。在具体调度器上安排的任务将严格遵循该时钟所表示的时间。
调度器类型可以通过`Schedule`的静态属性返回其中每种类型的调度器
| 调度器 | 目的 |
| ------------- |:-------------:|
| null | 不传递任何调度器的话,会以同步递归的方式发送通知。用于定时操作或尾递归操作。 |
| Rx.Scheduler.queue | 当前事件帧中的队列调度(蹦床调度器)。用于迭代操作。|
| Rx.Scheduler.asap | 微任务的队列调度,它使用可用的最快速的传输机制,比如 Node.js 的 process.nextTick() 或 Web Worker 的 MessageChannel 或 setTimeout 或其他。用于异步转换。|
| Rx.Scheduler.async | 使用 setInterval 的调度。用于基于时间的操作符。 |
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment