Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
log
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
zerozou
log
Commits
57e7604b
Commit
57e7604b
authored
Aug 29, 2017
by
zerozou
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add 2017.8.29 log:RxJS
parent
b1b2120d
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
256 additions
and
0 deletions
+256
-0
29.md
2017/08/29.md
+256
-0
No files found.
2017/08/29.md
0 → 100644
View file @
57e7604b
# 2017/8/29
## RxJS
*
通过使用 observable 序列来编写异步和基于事件的程序
注册事件监听器的常规写法
```javascript
let button = document.querySelector('button')
button.addEventListener('click', () => console.log('clicked'))
```
使用Rx创建一个Observable来写
```javascript
let button = document.querySelector('button')
Rx.Observable.fromEvent(button, 'click')
.subscribe(() => console.log('clicked'))
```
*
RxJS的优势
*纯净性(Purity)*
使用纯函数来产生值,常规的可能会共享外部变量写出一个非纯函数,增加出错率
```javascript
// 常规写法
let button = document.querySelector('button')
let count = 0
button.addEventListener('click', () => console.log(`clicked ${++count}`))
// RxJS写法
Rx.Observable.fromEvent(button, 'click')
.scan(count => count + 1, 0)
.subscribe(count => console.log(`clicked ${count}`))
```
`scan` 操作符的原理和 `reduce` 类似,需要给回调函数一个初始值,每次回调函数的返回值会作为下次回调函数的参数
*流动性(Flow)*
RxJS提供一套操作符来帮助我们控制事件如何流经Observable
```javascript
// 控制1s内最多点击一次
// 常规写法
let button = document.querySelector('button')
let count = 0
let rate = 1000
let lastClick = Date.now() - rate
button.addEventListener('click', () => {
if (Date.now() - lastClick >= rate) {
console.log(`clicked ${++count}`)
lastClick = Date.now()
}
})
// RxJS写法
Rx.Observable.fromEvent(button, 'click')
.throttleTime(1000)
.scan(count => count + 1, 0
.subscribe(count => console.log(`clicked ${count}`))
```
*值(Values)*
RxJS可以转换流经Observable的值
```javascript
// RxJS写法
Rx.Observable.fromEvent(button, 'click')
.throttleTime(1000)
.map(event => event.clientX)
.scan((count, clientX) => count + clientX, 0)
.subscribe(count => console.log(`clicked ${count}`))
```
*
Observable
订阅Observable与调用函数类似,但是Observable可以随着时间推移“返回”多个值,这是函数做不到的。
Observables是同步执行的
```javascript
let observable = Rx.Observable.create(observer => {
console.log('Hello')
observer.next(42)
})
console.log('before')
observable.subscribe(x => console.log(x))
console.log('after')
/*
* before
* hello
* 42
* after
*/
```
可同步“返回”值也可异步“返回”值
```javascript
let observable = Rx.Observable.create(observer => {
observer.next(1)
setTimeout(() => {
observer.next(2)
}, 1000)
})
console.log('before')
observable.subscribe(x => console.log(x))
console.log('after')
/*
* before
* 1
* after
* 2
*/
```
*创建Observables*
Rx.Observable.create是Observable构造函数的别名,并接受一个名为subscribe的函数
下例创建一个Observable,并每隔一秒向观察者发送字符串‘hi’
```javascript
let observable = Rx.Observable.create(function subscribe(observer) {
setInterval(() => {
observer.next('hi')
}, 1000)
})
```
*订阅Observables*
可以如下订阅
```javascript
observable.subscribe(x => console.log(x))
```
`observable.subscribe`
与
`Observable.create(function subscribe(observer){ ... })`
是不同的,但从实际角度出发,概念是相同的
这表明
`subscribe`
调用在同一 Observable 的多个观察者之间是不共享的。
*执行Observables*
`Observable.create(function subscribe(observer){ ... })`
中的...代码表示Observable执行,惰性运算,只有在每个观察者被订阅后才会执行。随时间推移,执行会以同步或者异步产生一个或多个值。
Observable执行可以传递三种类型的值:
*
“Next”通知:发送一个值(数字,字符串,对象……)
*
“Error”通知:发送一个错误或异常
*
“Complete”通知:不再发送值
“Error”和“Complete”只会在Observable执行期间发生一次,并且只会发生其中一个
*清理Observable执行*
当调用了
`observable.subscribe`
,观察者会被附加到新创建的Observable执行中,这个返回一个
`Subscription`
对象
```javascript
let subscription = observerable.subscribe(x => console.log(x))
```
可以使用这个对象调用
`unsubscribe`
方法来清Observable执行
```javascript
let observable = Rx.Observable.from([10, 20, 30])
let subscription = observable.subscribe(x => console.log(x))
// 稍后:
subscription.unsubscribe()
```
当使用
`create()`
创建Observable时,Observable必须定义如何清理执行的资源,你可以通过在
`function subscribe(){ ... }`
中返回一个自定义的
`unsubscribe`
函数
```javascript
let observable = Rx.Observable.create(function subscribe(observer) {
let intervalId = setTimeInterval(() => {
observer.next('hi')
}, 1000)
return function unsubscribe() {
clearInterval(intervalId)
}
})
```
*
Observer
Observer是由Observable发送的值的消费者,一组回调函数的集合,每个回调函数对应不同的通知类型
`next`
、
`error`
、
`complete`
```javascript
let observer = {
next: x => console.log(`next ${x}`),
error: err => console.error(`error ${err}`),
complete: () => console.log('complete'),
}
```
Observer可以只有部分回调函数,Observable能正常执行,只是会忽略掉某些通知类型。
当订阅Observable的时候,可以只传一个回调函数作为参数,而并没有将其附加到观察者对象上。
```javascript
observable.subscribe(x => console.log(x))
```
在 observable.subscribe 内部,它会创建一个观察者对象并使用第一个回调函数参数作为 next 的处理方法。所有三种类型的回调函数都可以直接作为参数来提供:
```javascript
observable.subscribe(
x => console.log(x),
err => console.error(err),
() => console.log('complete')
)
```
*
Subscription
Subscription表示可清理资源的对象,通常是Observable的执行。
Subscription三个方法:
*`unsubscribe`*
用来清理Observable的执行
```javascript
let observable = Rx.Observable.interval(1000)
let subscription = observable.subscribe(x => console.log(x))
subscription.unsubscribe()
```
*`add`*
把Subscription组合在一起,可以同时取消多个订阅
```javascript
let observable1 = Rx.Observable.interval(1000)
let observable2 = Rx.Observable.interval(2000)
let subscription1 = observable1.subscribe(x => console.log(x))
let subscription2 = observable2.subscribe(x => console.log(x))
subscription1.add(subscription2)
subscription1.unsubscribe()
```
*`remove`*
用来撤销已添加的Subscription
```javascript
subscription1.remove(subscription2)
```
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment