Rxjs 是一种针对异步数据流编程工具,或者叫响应式扩展编程,目的就是异步编程,在 angular 内置包含,直接引入使用即可,常用的 Observable 和 fromEvent
callback 和 promise 异步获取数据
name: any = 'bob'
getData () {
// Callback 异步获取数据
function callback (cb) {
setTimeout(() => {
cb('lucy1')
}, 1000)
}
callback(data => {
this.name = data
})
// Promise 异步获取数据
new Promise(resolve => {
setTimeout(() => {
resolve('lucy2')
}, 2000)
}).then(data => {
this.name = data
})
}
Rxjs 异步获取数据
import { Observable } from 'rxjs'
name: any = 'bob'
getData () {
// Rxjs 异步获取数据
new Observable(observer => {
setTimeout(() => {
observer.next('lucy3')
// observer.error(new Error('error'))
}, 3000)
}).subscribe(data => {
this.name = data
})
}
从上面看类似于 Promise 的用法,Promise 里面的 resolve() 和 then()
替换为 Rxjs 里面的 .next() 和 subscribe()
,但实际 Rxjs 比 Promise 要强大很多,比如 Rxjs 可以中途撤回、可以发射多个值、提供了多种工具函数等
Rxjs unsubscribe 取消订阅(中途执行)
name: any = 'bob'
getData () {
// Rxjs 异步获取数据
let streem = new Observable(observer => {
setTimeout(() => {
observer.next('lucy3')
// observer.error(new Error('error'))
}, 3000)
})
let cancel = streem.subscribe(data => {
this.name = data
})
// 1 秒钟后取消订阅
setTimeout(() => {
cancel.unsubscribe()
}, 1000)
}
Rxjs 订阅后多次执行
对于 Promise 无法做到 setInterval()
的多次执行,因为其状态只有 resolve 和 reject 两种且只能触发一次,而 Observable 可以不断触发
name: any = 'bob'
getData () {
// Rxjs 执行多次
let streem = new Observable(observer => {
let num = 1
setInterval(() => {
observer.next(`lucy${num++}`)
// observer.error(new Error('error'))
}, 3000)
})
streem.subscribe(data => {
this.name = data
})
}
Rxjs 的工具函数 map、filter 和 throttleTime
filter:对数据进行筛选过滤
map:对数据进行修改,类似原始 js 的 map
throttleTime:对数据延迟执行处理
import { map, filter, throttleTime } from 'rxjs/operators'
name: any = 'bob'
getCallbackData () {
let streem = new Observable(observer => {
let num = 1
setInterval(() => {
observer.next(num++)
// observer.error(new Error('error'))
}, 100)
})
streem.pipe(
// 筛选过滤出偶数进行赋值
filter((val: number): boolean => {
return Boolean(val % 2 === 0)
}),
// 对数据进行修改
map((val: number): number => {
return val * val
}),
// 对数据延迟执行处理
throttleTime(3000),
).subscribe(data => {
this.name = data
})
}