观察者模式 (Observer Pattern)

观察者模式其实在日常编码中经常遇到,比如DOM的事件监听,代码如下

function clickHandler(event) {
console.log('user click!');
}
document.body.addEventListener('click', clickHandler)

简而言之:观察者模式就如同上代码,有一个事件源‘dom 的click事件’ 也就是abservable,有一个观察者abserver clickHandler函数,有一个订阅机制(addEventLister),当dom的click事件触发时候,会通过订阅机制通知abserver 执行函数clickHandler函数。

下面是构建一个观察者模式的简单例子

function Producer() {

    // 这个 if 只是避免使用者不小心把 Producer 当作函式来调用
if(!(this instanceof Producer)) {
throw new Error('请用 new Producer()!');
// 仿 ES6 行为可用: throw new Error('Class constructor Producer cannot be invoked without 'new'')
} 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);
})
}

接下来建立实例

var egghead = new Producer();
// new 出一个 Producer 实例叫 egghead function listener1(message) {
console.log(message + 'from listener1');
} function listener2(message) {
console.log(message + 'from listener2');
} egghead.addListener(listener1); // 注册监听
egghead.addListener(listener2); egghead.notify('A new course!!') // 当某件事情方法时,执行
//a new course!! from listener1
//a new course!! from listener2

迭代器模式 (Iterator Pattern)

Iterator 是一个物件,它的就像是一个指针(pointer),指向一个资料结构并产生一个序列(sequence),这个序列会有资料结构中的所有元素(element)。

迭代者(Iterator,也称为“迭代器”)指的是能够遍历⼀个数据集合的对象,因为数据集合的实现⽅式很多,可以是⼀个数组,也可以是⼀个树形结构,也可以是⼀个单向链表……迭代器的作⽤就是提供⼀个通⽤的接口,让使⽤者完全不⽤关⼼这个数据集合的具体实现⽅式。

自己实现简单的迭代器

function IteratorFromArray(arr) {
if(!(this instanceof IteratorFromArray)) {
throw new Error('请用 new IteratorFromArray()!');
}
this._array = arr;
this._cursor = 0;
} IteratorFromArray.prototype.next = function() {
return this._cursor < this._array.length ?
{ value: this._array[this._cursor++], done: false } :
{ done: true };
}

补充 - ES6 生成器

生成器是一种返回迭代器的函数,通过function关键字后的星号(*)来表示,函数中会用到新的关键字yield。星号可以紧挨着function关键字,也可以在中间添加一个空格

// 生成器
function *createIterator() {
yield 1;
yield 2;
yield 3;
}
// 生成器能像正规函数那样被调用,但会返回一个迭代器
let iterator = createIterator();
console.log(iterator.next().value); // 1
console.log(iterator.next().value); // 2
console.log(iterator.next().value); // 3 function *createIterator(items) {
for (let i = 0; i < items.length; i++) {
yield items[i];
}
}
let iterator = createIterator([1, 2, 3]);
console.log(iterator.next()); // "{ value: 1, done: false }"
console.log(iterator.next()); // "{ value: 2, done: false }"
console.log(iterator.next()); // "{ value: 3, done: false }"
console.log(iterator.next()); // "{ value: undefined, done: true }"
// 之后的所有调用
console.log(iterator.next()); // "{ value: undefined, done: true }"

Observable 其实就是这两个 Pattern 思想的结合,Observable 具备生产者推送资料的特性,同时能像序列,拥有序列处理资料的方法(map, filter...)!

更简单的来说,Observable 就像是一个序列,裡面的元素会随著时间推送。

rxjs入门4之rxjs模式设计的更多相关文章

  1. RxJS入门2之Rxjs的安装

    RxJS V6.0+ 安装 RxJS 的 import 路径有以下 5 种: 1.创建 Observable 的方法.types.schedulers 和一些工具方法 import { Observa ...

  2. Android 腾讯入门教程( 智能手表UI设计 和 MVC模式 )

    *****注意到mvc 在android 中是如何进行分层分域执行各自的功能.**** 官方推荐的按钮尺寸是48像素 前端之Android入门(1):环境配置 前端之Android入门(2):程序目录 ...

  3. RxJS入门

    一.RxJS是什么? 官方文档使用了一句话总结RxJS: Think of RxJS as Lodash for events.那么Lodash主要解决了什么问题?Lodash主要集成了一系列关于数组 ...

  4. Rxjs入门实践-各种排序算法排序过程的可视化展示

    Rxjs入门实践-各种排序算法排序过程的可视化展示 这几天学习下<算法>的排序章节,具体见对排序的总结,想着做点东西,能将各种排序算法的排序过程使用Rxjs通过可视化的方式展示出来,正好练 ...

  5. 分享基于Entity Framework的Repository模式设计(附源码)

    关于Repository模式,在这篇文章中有介绍,Entity Framework返回IEnumerable还是IQueryable? 这篇文章介绍的是使用Entity Framework实现的Rep ...

  6. php模式设计之 观察者模式

    这是我写的<php模式设计>的第五篇.前面的四篇在不断学习不断加深认识,到了今天再看观察者模式,觉得非常容易理解.这也许就是我们积少成多的结果吧.希望还是能够不断进步. 开篇还是从名字说起 ...

  7. php模式设计之 适配器模式

    在这个有没有对象都要高呼“面向对象”的年代,掌握面向对象会给我们带来意想不到的方便.学编程的小伙伴从开始能写几行代码实现简单功能到后来懂得将一些重复的操作组合起来形成一个“函数”,再到后来将“函数”和 ...

  8. php模式设计之 注册树模式

    在前两篇单例模式和工厂模式后,终于迎来了最后一个基础的设计模式--注册树模式. 什么是注册树模式? 注册树模式当然也叫注册模式,注册器模式.之所以我在这里矫情一下它的名称,是因为我感觉注册树这个名称更 ...

  9. php模式设计之 工厂模式

    承接上篇php模式设计之 单例模式,(虽然好像关系不大).今天讲述第二种基础的模式设计——工厂模式. 那么何为工厂模式? 从名字来看,似乎看不出什么端倪.工厂模式,和生产有关?还是和生产流程有关?难道 ...

随机推荐

  1. golang 内置print/println、fmt、log的区别

    fmt.Println与fmt.Print区别 换行区别不用多说,另外一个区别在于fmt.Print只有在参数间都不是字符串时才会产生间隔 fmt与log的重要区别 fmt没有做同步处理 fmt标准输 ...

  2. C#知识点:抽象类和接口浅谈

    首先介绍什么是抽象类? 抽象类用关键字abstract修饰的类就是叫抽象类,抽象类天生的作用就是被继承的,所以不能实例化,只能被继承.而且 abstract 关键字不能和sealed一起使用,因为se ...

  3. axure rp extension for chrome怎么用

    1)打开文件(原型图)的resources文件夹>chrome文件夹>将文件axure-chrome-extension.crx拉至谷歌浏览器的扩展程序页面,点击确定添加 2)提示出错时, ...

  4. Kubernetes 初体验(先占个坑)

  5. boot 项目启动报Cannot datermine embedded database driver class for database type NONE

    部署boot项目时报Cannot datermine embedded database driver class for database type NONE数据库链接什么的也都没有问题,经过百度 ...

  6. PHP的七个数组指针函数

    1. PHP的七个数组指针函数 函数 描述 reset() 将一个数组的内部指针重置到首位,并返回第一个元素的值 end() 将一个数组的内部指针移动到数组的最后一个元素所在的位置,并返回最后一个元素 ...

  7. Lua GC机制

    说明 分析lua使用的gc算法,如何做到分步gc,以及测试结论 gc算法分析 lua gc采用的是标记-清除算法,即一次gc分两步: 从根节点开始遍历gc对象,如果可达,则标记 遍历所有的gc对象,清 ...

  8. 恭喜!Apache Hudi社区新晋多位Committer

    1. 介绍 经过Apache Hudi项目委员会讨论及投票,向Udit Mehrotra.Gary Li.Raymond Xu.Pratyaksh Sharma 4人发出Committer邀请,4人均 ...

  9. jmeter进行MySQL压测

    jmeter怎么对数据库进行压测 目录 jmeter怎么对数据库进行压测 点击测试计划,再点击"浏览",把JDBC驱动添加进来: 然后添加配置元件 再添加一个采样器:JDBC re ...

  10. js监听事件的绑定与移除

    监听事件的绑定与移除主要是addEventListener和removeEventListener的运用. addEventListener语法 element.addEventListener(ty ...