vue的响应式

JS设计模式之订阅发布模式

2021-05-09  本文已影响0人  Splendid飞羽

定义:订阅发布模式定义了对象间一种一对多的关系,让多个观察者对象同时监听同一主题对象,当一个对象改变时,所有依赖于它的对象都将得到通知。

优点:

缺点

核心:订阅者、发布者

1、实现原理:

下面是一个简单的订阅发布的js示例

var shoeObj = {}; // 定义发布者
shoeObj.list = []; // 缓存列表 存放订阅者回调函数
        
// 增加订阅者
shoeObj.listen = function(fn) {
    shoeObj.list.push(fn);  // 订阅消息添加到缓存列表
}

// 发布消息
shoeObj.trigger = function(){
    for(var i = 0,fn; fn = this.list[i++];) {
        fn.apply(this,arguments); 
    }
}
// 小红订阅如下消息
shoeObj.listen(function(color,size){
    console.log("颜色是:"+color);
    console.log("尺码是:"+size);  
});

// 小花订阅如下消息
shoeObj.listen(function(color,size){
    console.log("再次打印颜色是:"+color);
    console.log("再次打印尺码是:"+size); 
});
shoeObj.trigger("红色",40);
shoeObj.trigger("黑色",42);
// 颜色是:红色
// 尺码是:40
// 再次打印颜色是:红色
// 再次打印尺码是:40
// 颜色是:黑色
// 尺码是:42
// 再次打印颜色是:黑色
// 再次打印尺码是:42

参考我的印象笔记

2、源码中的发布-订阅模式**

发布-订阅模式在源码中应用很多,特别是现在很多前端框架都会有的双向绑定机制的场景,这里以现在很火的 Vue 为例,来分析一下 Vue 是如何利用发布-订阅模式来实现视图层和数据层的双向绑定。先借用官网的双向绑定原理图:

image

下面稍微解释一下这个图(框架源码整个过程比较复杂,如果现在看不懂下面几段也没关系,大致了解一下即可)。

组件渲染函数(Component Render Function)被执行前,会对数据层的数据进行响应式化。响应式化大致就是使用 Object.defineProperty 把数据转为 getter/setter,并为每个数据添加一个订阅者列表的过程。这个列表是 getter 闭包中的属性,将会记录所有依赖这个数据的组件。

我们可以看看 Vue 的源码:

// src/core/observer/index.js 响应式化过程

Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter() {
        // ...
        const value = getter ? getter.call(obj) : val // 如果原本对象拥有getter方法则执行
        dep.depend()                     // 进行依赖收集,dep.addSub
        return value
    },
    set: function reactiveSetter(newVal) {
        // ...
        if (setter) { setter.call(obj, newVal) }    // 如果原本对象拥有setter方法则执行
        dep.notify()               // 如果发生变更,则通知更新
    }
})

而这个 dep 上的 dependnotify 就是订阅和发布通知的具体方法。

3、发布-订阅模式的优缺点

发布-订阅模式最大的优点就是解耦:

发布-订阅模式也有缺点:

4、发布订阅模式与其他设计模式的区别

发布-订阅模式和观察者模式

观察者模式与发布-订阅者模式,在平时你可以认为他们是一个东西,但是某些场合(比如面试)下可能需要稍加注意,借用网上一张流行的图:

image

区别主要在发布-订阅模式中间的这个 Event Channel:

发布-订阅模式和责任链模式

发布-订阅模式和责任链模式也有点类似,主要区别在于:

任务:手写发布订阅模式

上一篇下一篇

猜你喜欢

热点阅读