前言
NodeJS这东西是不是学过了,之后感觉又像没学到什么东西???
我最近翻到了之前学习node的笔记,又结合了一些大佬的经验,这里把node系列相关的东西串联一下,分享给小伙伴们,顺便我自己也加深一下印象。
总共分为六篇
node打怪升级系列 – 手写中间件篇
node打怪升级系列 – 手写发布订阅和观察者篇
node打怪升级系列 – 手写compose(洋葱模型)
本文重点记录下发布订阅和观察者篇
里的装备
正文开始
Node
中很多内置模块,比如http
net
都是基于发布订阅
实现的
发布订阅
和观察者模式
其实我一直觉得它就是一种东西,直到听到一大佬说这是两种设计模式
1,发布订阅
让自定义的函数,在该执行的时候执行
EventEmitter
是Node
中做事件驱动的,EventTarget
是浏览器
中做事件驱动的。
两个类的宿主环境是不一样的
上栗子
1.1,EventEmitter
const EventEmitter = require('events').EventEmitter;
const e = new EventEmitter()
e.on('test', (data)=>{
console.log(data) // 1s后打印'巴拉巴拉'
})
setTimeout(function() {
e.emit('test', '巴拉巴拉');
}, 1000);
1.2,EventTarget
const e = new EventTarget();
e.addEventListener('test', (data)=>{
console.log(data) // 1s后打印'巴拉巴拉'
})
setTimeout(function() {
e.dispatchEvent('test', '巴拉巴拉');
}, 1000);
1.3,手戳发布订阅
顺嘴一提,构造函数
和类
都是能被new
的
至于构造函数是什么?
, new的时候发生了什么?
, 手戳一个new
,以后单独出一篇讲,此处重点围绕发布订阅
此处用构造函数
的方式写
function EventEmitter() {
this.events = {} // 事件对象
}
EventEmitter.prototype.on = (eventName, cb) => {
if (!this.events) this.events = {}
let eventList = this.events[eventName] || (this.events[eventName] = [])
eventList.push(cb)
}
EventEmitter.prototype.emit = (eventName, ...rest) => {
this.events[eventName] && this.events[eventName].forEach(cb => cb(...rest));
}
发布订阅的核心就是上面这行代码啦, 是不是很简洁~~~
使用如下
要点解析:
我看了半天好像只有这句话可能需要再聊下
let eventList = this.events[eventName] || (this.events[eventName] = [])
等于
this.events[eventName] = this.events[eventName] || []
let eventList = this.events[eventName] || []
通俗的说,这是活用引用类型
里的引用关系达到简写的目的
对象属于引用类型,字符串/数字/布尔/null/undefined等属于基本类型
eventList
和this.events[eventName]
建立了引用关系,eventList.push(xx)
就等于this.events[eventName].push(xx)
let a = '哈哈'
let b = '哈哈'
let c = {}
let d = {}
累了,喝口水休息会吧
2,观察者模式
此处用类
的方式写
// 主对象/中央厨房
class Subject {
constructor() {
this.deps = []
}
attach(customer) {
this.deps.push(customer)
}
// 进行广播,通知所有顾客
notifyAll(food) {
this.deps.forEach((customer) => {
if (food === customer.food) customer.update()
})
}
}
// 观察者/顾客
class Observer {
constructor(name, food) {
this.name = name
this.food = food
}
update() {
console.log(`你好 ${this.name},你的${this.food}做好了`)
}
}
使用
// 顾客张XX来了,点了一份宫保鸡丁
let customer1 = new Observer('张XX', '宫保鸡丁')
// 顾客李XX来了,点了一份糖醋鱼
let customer2 = new Observer('李XX', '糖醋鱼')
let subject = new Subject()
// 告诉中央厨房做一份宫保鸡丁
subject.attach(customer1)
// 告诉中央厨房做一份糖醋鱼
subject.attach(customer2)
// 糖醋鱼做好了,大喇叭响起来了,李XX 你点的糖醋鱼好了
subject.notifyAll('糖醋鱼')
3,发布订阅和观察者的区别
小伙伴们应该能发现
发布订阅模式
是有一个类似第三方机构处理监听事件(on)、执行事件(emit),emit和on不存在耦合
观察者模式
的主对象和观察者是有依赖关系的, 存在耦合的
完结
这篇文章我尽力把我的笔记和想法放到这了,希望对小伙伴有帮助。
欢迎转载,但请注明来源。
最后,希望小伙伴们给我个免费的点赞,祝大家心想事成,平安喜乐。
原文链接:https://juejin.cn/post/7321643424952549391 作者:尘落笔记