Skip to content

不要关注

观察者模式

前言

如果前端只学一种设计模式,那无疑就是观察者模式

介绍

发布 & 订阅

一对 n

示例

点咖啡,点好之后坐等被叫

订报纸

订阅公众号

代码演示

javascript
// 主题,保存状态,状态变化之后出发所有观察者对象
class Subject {
    constructor() {
        this.state = 0;
        this.observers = [];
    }
    getState() {
        return this.state;
    }
    setState(state) {
        this.state = state;
        this.notifyAllObservers();
    }
    notifyAllObservers() {
        this.observers.forEach((observer) => {
            observer.update();
        });
    }
    attach(observer) {
        this.observers.push(observer);
    }
}

// 观察者
class Observer {
    constructor(name, subject) {
        this.name = name;
        this.subject = subject;
        this.subject.attach(this);
    }
    update() {
        console.log(`${this.name} update, state: ${this.subject.state}`);
    }
}

const s = new Subject();
const o1 = new Observer('o1', s);
const o2 = new Observer('o2', s);
const o3 = new Observer('o3', s);

s.setState(1);
s.setState(2);
s.setState(3);

场景

网页事件绑定

Promise

jQuery Callbacks

nodejs 自定义事件

网页事件绑定

html
<button id="btn1">btn</button>
<script>
    $('#btn1').click(function () {
        console.log(1);
    });
    $('#btn1').click(function () {
        console.log(2);
    });
    $('#btn1').click(function () {
        console.log(3);
    });
</script>

元素 btn1 就是 Subject(主题),点击(click)它,发生变化,打印

Promise

javascript
function loadImg(src) {
    var promise = new Promise(function (resolve, reject) {
        var img = document.createElement('img')
        img.onload = function () {
            resolve(img)
        }
        img.onerror = function () {
            reject('图片加载失败')
        }
        img.src = src
    })
    return promise
}
var src 'https://www.baidu.com/xxx'
var result = loadImg(src)
result.then(function(img) {
    console.log('width', img.width)
    return img
}).then(function (img) {
    console.log('height', img.height)
})

jQuery Callbacks

javascript
var callbacks = $.Callbacks();
callbacks.add(function (info) {
    console.log('fn1', info);
});
callbacks.add(function (info) {
    console.log('fn2', info);
});
callbacks.add(function (info) {
    console.log('fn3', info);
});
callbacks.fire('gogogo');

往 callbacks 中添加主题,再 fire(触发)

nodejs 自定义事件

javascript
const EventEmitter = require('events').EventEmitter;

const emitter1 = new EventEmitter();
emitter1.on('some', () => {
    // 监听 some 事件
    console.log('some event is occured 1');
});
emitter1.on('some', () => {
    // 监听 some 事件
    console.log('some event is occured 2');
});
// 触发 some 事件
emitter1.emit('some');

其他场景

nodejs 中:处理 http 请求;多进程通讯

vue 和 React 组件生命周期触发

vue watch

http 请求

javascript
function serverCallback(req, res) {
    var method = req.method.toLowerCase(); // 获取请求方法
    if (method === 'get') {
        // ...
    }
    if (method === 'post') {
        // 接收 post 请求的内容
        var data = '';
        req.on('data', function (chunk) {
            // 一点点 接受内容
            data += chunk.toString();
        });
        req.on('end', function () {
            // 接收完毕,将内容输出
            res.writeHead(200, { 'Content-type': 'text/html' });
            res.write(data);
            res.end();
        });
    }
}

参考资料