RxJS 笔记 04
1 Observer Pattern
观察者模式
典型例子: DOM的事件监听
function clickHandler(event) {
console.log('user click!');
}
document.body.addEventListener('click', clickHandler)
手写练习
function Producer() {
// 这个 if 只是避免使用者不小心把 Producer 当作函数来调用
if (!(this instanceof Producer)) {
// 仿 ES6 行为可用
throw new Error('请用 new Producer()!');
}
this.listeners = [];
}
// 加入监听方法
Producer.prototype.addListener = function(listener) {
if (typeof listener === 'function') {
this.listeners.push(listener)
} else {
throw new Error('listener 必须是 function')
}
}
// 移除监听的方法
Producer.prototype.removeListener = function(listener) {
this.listeners.splice(this.listeners.indexOf(listener), 1)
}
// 发送通知的方法
Producer.prototype.notify = function(message) {
this.listeners.forEach(listener => {
listener(message)
})
}
class Producer {
constructor() {
this.listeners = [];
}
addListener(listener) {
if (typeof listener === 'function') {
this.listeners.push(listener)
} else {
throw new Error('listener 必须是 function')
}
}
removeListener(listener) {
this.listeners.splice(this.listeners.indexOf(listener), 1)
}
notify(message) {
this.listeners.forEach(listener => {
listener(message)
})
}
}
2 Iterator Pattern
迭代器模式
它就像是一个指针(pointer),指向一个资料结构并产生一个序列(sequence)
这个序列会有资料结构中的所有元素(element)
练习
var arr = [1,2,3];
var iterator = arr[Symbol.iterator]();
iterator.next()
// {value: 1, done: false}
interator.next()
// {value: 2, done: false}
interator.next()
// {value: 3, done: false}
interator.next()
// {value: undefined, done: true}
JS到了ES6才有原生的Iterator
JS的采用functional的做法,在取得最后一个元素之后
执行next
永远都回传 {done:true, value:undefined}
最后一个元素前
: {done:true, value:elem}
最后一个元素之后
: {done:false, value:undefined}
练习
function InteratorFromArray(arr) {
if (!(this instanceof InteratorFromArray)) {
throw new Error('请用 new InteratorFromArray()!')
}
this._array = arr;
this._cursor = 0;
}
InteratorFromArray.prototype.next = function() {
return this._cursor < this._array.length ?
{ value: this._array[this._cursor++], done: false } :
{ done: true }
}
class InteratorFromArray {
constructor(arr) {
this._array = arr;
this._cursor = 0;
}
next() {
return this._cursor < this._array.length ?
{ value: this._array[this._cursor++], done: false } :
{ done: true }
}
}
2-1 优势
- 渐进式取得资料的特性可以拿来做延迟运算(Lazy evaluation), 让我们能用它处理大资料结构
- 本事序列,所以可以实作所有阵列的运算方法 像 map, filter…等
延迟迭代器,call-by-need
function* getNumbers(words) {
for (let word of words) {
if (/^[0-9]+$/.test(word)) {
yield parseInt(word, 10);
}
}
}
const interator = getNumbers('30 天精通 RxJS (04)');
interator.next();
// {value: 3, done:false}
interator.next();
// {value:0, done:false}
interator.next();
// {value:0, done:false}
interator.next();
// {value:4, done:false}
interator.next();
// {value:undefined, done:true}
map迭代器
class InteratorFromArray {
constructor(arr) {
this._array = arr;
this._cursor = 0;
}
next() {
return this._cursor < this._array.length ?
{value: this._array[this._cursor++], done:false} :
{done:true}
}
map(callback) {
const iterator = new InteratorFromArray(this._array);
return {
next: () => {
const {done, value} = iterator.next();
return {
done: done,
value: done ? undefined : callback(value)
}
}
}
}
}
let interator = new InteratorFromArray([1,2,3]);
let newInterator = interator.map(value => value + 3);
newInterator.next();
// {value:4, done:false}
newInterator.next();
// {value:5, done:false}
newInterator.next()
// {value:6, done:false}
newInterator.next()
// {value:undefined, done:true}
3 Observer Pattern
观察者模式 & Iterator Pattern
迭代器模式
Observer 跟 Iterator 共通的特性
- 都是 渐进式(progressive) 的取得资料
Observer 跟 Iterator 区别
- Observer 是生产者(Producer)推送资料(push)
- Iterator 是消费者(Consumer)要求资料(pull)
4 Observable
简介
Observable 其实就是这两个 Pattern 思想的结合,
- 具备生产者推送资料的特性,
- 同时能像序列,拥有序列处理资料的方法(map, filter…)!