区块链技术博客
www.b2bchain.cn

五、3. 观察者模式求职学习资料

D0b2wT.gif

本文介绍了五、3. 观察者模式求职学习资料,有助于帮助完成毕业设计以及求职,是一篇很好的资料。

对技术面试,学习经验等有一些体会,在此分享。

观察者模式也可以称之为监听者模式。

它由观察者「Observer」与被观察者「Subject」共同组成。

五、3. 观察者模式

又名发布订阅模式,在复杂场景下,为了适应更多需求,除了观察者与被观察者,还会引入更多的角色,因此复杂场景下,大家更愿意称之为发布订阅模式。

我们会遇到很多这种场景,例如事件监听。当我们点击按钮时,对应按钮如果添加了点击事件监听,那么对应的逻辑就会自动执行。而不需要我们显示的调用该逻辑去执行他。

我们也可以自定义事件。

var event = new Event('build')  // 添加观察者 document.addEventListener('build', function () {   console.log('我是新增的一个观察者1,我现在观察到 document 触发了 build 事件') })  // 添加观察者 document.addEventListener('build', function () {   console.log('我是新增的一个观察者2,我现在观察到 document 触发了 build 事件') })  // 被观察者触发事件 document.dispatchEvent(event)

观察者模式解决的就是这样的问题。当某一个条件满足要求或者触发某一种事件时,所有的观察者都会感知到并执行对应的逻辑。

在前端里最常见的就是 React/Vue 的数据思维:当我们改变 state/data 里的数据时,就会自动渲染 UI。

五、3. 观察者模式

上图就是 Vue 的内部原理,观察者 Observer 观察数据 Data 的变化,如果一旦发现数据产生了变化就会通知后续的流程,最终完成 View 的更新。

基本实现

代码逻辑比较简单,直接上代码。

let subjectid = 0 let observerid = 0  class Subject {   constructor(name) {     // 观察者队列     this.observers = []     this.id = subjectid++     this.name = name   }    // 添加观察者   addListener(observer) {     this.observers.push(observer)   }    // 删除观察者   removeListener(observer) {     this.observers = this.observers.filter(item => item.id !== observer.id)   }    // 通知   dispatch() {     this.observers.forEach(item => {       item.watch(this.name)     })   } }  class Observer {   constructor() {     this.id = observerid++   }   watch(subjectName) {     console.log(`观察者${this.id}发现了被观察者 ${subjectName} 产生了变化。`)   } }  const sub = new Subject('div元素') const observer1 = new Observer() const observer2 = new Observer()  sub.addListener(observer1) sub.addListener(observer2)  sub.dispatch()

被观察者,通过 addListener 添加观察者。

当被观察者发生变化时,调用 sub.dispatch 通知所有观察者。

观察者通过 watch 接收到通知之后,执行预备好的逻辑。

以 DOM 元素事件绑定为例,我们进行一个类比

div.addEventListener('click', fn, false) div.addEventListener('mousemove', fn, false) div.addEventListener('mouseup', fn, false)

此时,被观察者,就是 div 元素。

没有明确的观察者,而是直接传入回调函数 fn,事件触发时,回调函数全部执行。因此也可以将此处的回调函数理解为观察者。

这种以回调函数作为观察者的方式更符合事件绑定机制。

此处还需要传入一个字符串用于区分事件类型。这种方式又应该怎么实现呢?

思考一下,直接上代码

class Subject {   constructor(name) {     // 观察者队列     // 格式为: { click: [fn1, fn2], scroll: [fn1, fn2] }     this.events = {}     this.name = name   }    // 添加观察者   addListener(type, fn) {     const cbs = this.events[type]     if (cbs && cbs.length > 0) {       const _cbs = cbs.filter(cb => cb != cbs)       _cbs.push(fn)       this.events[type] = _cbs     } else {       this.events[type] = [fn]     }   }    // 删除观察者   removeListener(type) {     delete this.events[type]   }    // 通知   dispatch(type) {     this.events[type].forEach(cb => cb())   } }  const sub = new Subject('div')  sub.addListener('build', function() {   console.log('build 事件触发1') }) sub.addListener('build', function () {   console.log('build 事件触发2') }) sub.addListener('click', function() {   console.log('click 事件触发') })  sub.dispatch('build')

Vue 的实现原理

五、3. 观察者模式

Vue 的核心是监听 data 中的数据变化,然后让数据的变化自动响应到 View 的变化。

由于 Vue 的场景更为复杂,因此在这个过程中引入了许多其他的角色。

Data:数据,最初的被观察者

Observer:Data 的观察者,数据劫持,监听数据的变化

Dep:订阅器,收集 Watcher。

Watcher:Dep 的订阅者,收到通知之后更新试图

数据的变化,会被 Observer 劫持,并且通知订阅器 Dep。Dep 收到通知之后,又会通知 Watcher,Watcher 收到属性的变化通知并执行响应的函数去更新试图 View。

Observer

data 数据的监听机制不需要我们去实现,因为在 JavaScript 中,对象中的每一个属性都具备自身的描述对象 descriptor

当访问数据时,描述对象中 get 方法会执行。

当修改数据时,描述对象中的 set 方法会执行。

观察者模式也可以称之为监听者模式。

它由观察者「Observer」与被观察者「Subject」共同组成。

五、3. 观察者模式

又名发布订阅模式,在复杂场景下,为了适应更多需求,除了观察者与被观察者,还会引入更多的角色,因此复杂场景下,大家更愿意称之为发布订阅模式。

我们会遇到很多这种场景,例如事件监听。当我们点击按钮时,对应按钮如果添加了点击事件监听,那么对应的逻辑就会自动执行。而不需要我们显示的调用该逻辑去执行他。

我们也可以自定义事件。

var event = new Event('build')  // 添加观察者 document.addEventListener('build', function () {   console.log('我是新增的一个观察者1,我现在观察到 document 触发了 build 事件') })  // 添加观察者 document.addEventListener('build', function () {   console.log('我是新增的一个观察者2,我现在观察到 document 触发了 build 事件') })  // 被观察者触发事件 document.dispatchEvent(event)

观察者模式解决的就是这样的问题。当某一个条件满足要求或者触发某一种事件时,所有的观察者都会感知到并执行对应的逻辑。

在前端里最常见的就是 React/Vue 的数据思维:当我们改变 state/data 里的数据时,就会自动渲染 UI。

五、3. 观察者模式

上图就是 Vue 的内部原理,观察者 Observer 观察数据 Data 的变化,如果一旦发现数据产生了变化就会通知后续的流程,最终完成 View 的更新。

基本实现

代码逻辑比较简单,直接上代码。

let subjectid = 0 let observerid = 0  class Subject {   constructor(name) {     // 观察者队列     this.observers = []     this.id = subjectid++     this.name = name   }    // 添加观察者   addListener(observer) {     this.observers.push(observer)   }    // 删除观察者   removeListener(observer) {     this.observers = this.observers.filter(item => item.id !== observer.id)   }    // 通知   dispatch() {     this.observers.forEach(item => {       item.watch(this.name)     })   } }  class Observer {   constructor() {     this.id = observerid++   }   watch(subjectName) {     console.log(`观察者${this.id}发现了被观察者 ${subjectName} 产生了变化。`)   } }  const sub = new Subject('div元素') const observer1 = new Observer() const observer2 = new Observer()  sub.addListener(observer1) sub.addListener(observer2)  sub.dispatch()

被观察者,通过 addListener 添加观察者。

当被观察者发生变化时,调用 sub.dispatch 通知所有观察者。

观察者通过 watch 接收到通知之后,执行预备好的逻辑。

以 DOM 元素事件绑定为例,我们进行一个类比

div.addEventListener('click', fn, false) div.addEventListener('mousemove', fn, false) div.addEventListener('mouseup', fn, false)

此时,被观察者,就是 div 元素。

没有明确的观察者,而是直接传入回调函数 fn,事件触发时,回调函数全部执行。因此也可以将此处的回调函数理解为观察者。

这种以回调函数作为观察者的方式更符合事件绑定机制。

此处还需要传入一个字符串用于区分事件类型。这种方式又应该怎么实现呢?

思考一下,直接上代码

class Subject {   constructor(name) {     // 观察者队列     // 格式为: { click: [fn1, fn2], scroll: [fn1, fn2] }     this.events = {}     this.name = name   }    // 添加观察者   addListener(type, fn) {     const cbs = this.events[type]     if (cbs && cbs.length > 0) {       const _cbs = cbs.filter(cb => cb != cbs)       _cbs.push(fn)       this.events[type] = _cbs     } else {       this.events[type] = [fn]     }   }    // 删除观察者   removeListener(type) {     delete this.events[type]   }    // 通知   dispatch(type) {     this.events[type].forEach(cb => cb())   } }  const sub = new Subject('div')  sub.addListener('build', function() {   console.log('build 事件触发1') }) sub.addListener('build', function () {   console.log('build 事件触发2') }) sub.addListener('click', function() {   console.log('click 事件触发') })  sub.dispatch('build')

Vue 的实现原理

五、3. 观察者模式

Vue 的核心是监听 data 中的数据变化,然后让数据的变化自动响应到 View 的变化。

由于 Vue 的场景更为复杂,因此在这个过程中引入了许多其他的角色。

Data:数据,最初的被观察者

Observer:Data 的观察者,数据劫持,监听数据的变化

Dep:订阅器,收集 Watcher。

Watcher:Dep 的订阅者,收到通知之后更新试图

数据的变化,会被 Observer 劫持,并且通知订阅器 Dep。Dep 收到通知之后,又会通知 Watcher,Watcher 收到属性的变化通知并执行响应的函数去更新试图 View。

Observer

data 数据的监听机制不需要我们去实现,因为在 JavaScript 中,对象中的每一个属性都具备自身的描述对象 descriptor

当访问数据时,描述对象中 get 方法会执行。

当修改数据时,描述对象中的 set 方法会执行。

观察者模式也可以称之为监听者模式。

它由观察者「Observer」与被观察者「Subject」共同组成。

五、3. 观察者模式

又名发布订阅模式,在复杂场景下,为了适应更多需求,除了观察者与被观察者,还会引入更多的角色,因此复杂场景下,大家更愿意称之为发布订阅模式。

我们会遇到很多这种场景,例如事件监听。当我们点击按钮时,对应按钮如果添加了点击事件监听,那么对应的逻辑就会自动执行。而不需要我们显示的调用该逻辑去执行他。

我们也可以自定义事件。

var event = new Event('build')  // 添加观察者 document.addEventListener('build', function () {   console.log('我是新增的一个观察者1,我现在观察到 document 触发了 build 事件') })  // 添加观察者 document.addEventListener('build', function () {   console.log('我是新增的一个观察者2,我现在观察到 document 触发了 build 事件') })  // 被观察者触发事件 document.dispatchEvent(event)

观察者模式解决的就是这样的问题。当某一个条件满足要求或者触发某一种事件时,所有的观察者都会感知到并执行对应的逻辑。

在前端里最常见的就是 React/Vue 的数据思维:当我们改变 state/data 里的数据时,就会自动渲染 UI。

五、3. 观察者模式

上图就是 Vue 的内部原理,观察者 Observer 观察数据 Data 的变化,如果一旦发现数据产生了变化就会通知后续的流程,最终完成 View 的更新。

基本实现

代码逻辑比较简单,直接上代码。

let subjectid = 0 let observerid = 0  class Subject {   constructor(name) {     // 观察者队列     this.observers = []     this.id = subjectid++     this.name = name   }    // 添加观察者   addListener(observer) {     this.observers.push(observer)   }    // 删除观察者   removeListener(observer) {     this.observers = this.observers.filter(item => item.id !== observer.id)   }    // 通知   dispatch() {     this.observers.forEach(item => {       item.watch(this.name)     })   } }  class Observer {   constructor() {     this.id = observerid++   }   watch(subjectName) {     console.log(`观察者${this.id}发现了被观察者 ${subjectName} 产生了变化。`)   } }  const sub = new Subject('div元素') const observer1 = new Observer() const observer2 = new Observer()  sub.addListener(observer1) sub.addListener(observer2)  sub.dispatch()

被观察者,通过 addListener 添加观察者。

当被观察者发生变化时,调用 sub.dispatch 通知所有观察者。

观察者通过 watch 接收到通知之后,执行预备好的逻辑。

以 DOM 元素事件绑定为例,我们进行一个类比

div.addEventListener('click', fn, false) div.addEventListener('mousemove', fn, false) div.addEventListener('mouseup', fn, false)

此时,被观察者,就是 div 元素。

没有明确的观察者,而是直接传入回调函数 fn,事件触发时,回调函数全部执行。因此也可以将此处的回调函数理解为观察者。

这种以回调函数作为观察者的方式更符合事件绑定机制。

此处还需要传入一个字符串用于区分事件类型。这种方式又应该怎么实现呢?

思考一下,直接上代码

class Subject {   constructor(name) {     // 观察者队列     // 格式为: { click: [fn1, fn2], scroll: [fn1, fn2] }     this.events = {}     this.name = name   }    // 添加观察者   addListener(type, fn) {     const cbs = this.events[type]     if (cbs && cbs.length > 0) {       const _cbs = cbs.filter(cb => cb != cbs)       _cbs.push(fn)       this.events[type] = _cbs     } else {       this.events[type] = [fn]     }   }    // 删除观察者   removeListener(type) {     delete this.events[type]   }    // 通知   dispatch(type) {     this.events[type].forEach(cb => cb())   } }  const sub = new Subject('div')  sub.addListener('build', function() {   console.log('build 事件触发1') }) sub.addListener('build', function () {   console.log('build 事件触发2') }) sub.addListener('click', function() {   console.log('click 事件触发') })  sub.dispatch('build')

Vue 的实现原理

五、3. 观察者模式

Vue 的核心是监听 data 中的数据变化,然后让数据的变化自动响应到 View 的变化。

由于 Vue 的场景更为复杂,因此在这个过程中引入了许多其他的角色。

Data:数据,最初的被观察者

Observer:Data 的观察者,数据劫持,监听数据的变化

Dep:订阅器,收集 Watcher。

Watcher:Dep 的订阅者,收到通知之后更新试图

数据的变化,会被 Observer 劫持,并且通知订阅器 Dep。Dep 收到通知之后,又会通知 Watcher,Watcher 收到属性的变化通知并执行响应的函数去更新试图 View。

Observer

data 数据的监听机制不需要我们去实现,因为在 JavaScript 中,对象中的每一个属性都具备自身的描述对象 descriptor

当访问数据时,描述对象中 get 方法会执行。

当修改数据时,描述对象中的 set 方法会执行。

部分转自互联网,侵权删除联系

赞(0) 打赏
部分文章转自网络,侵权联系删除b2bchain区块链学习技术社区 » 五、3. 观察者模式求职学习资料
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

b2b链

联系我们联系我们