美文网首页
观察者模式

观察者模式

作者: zxhnext | 来源:发表于2019-09-22 18:33 被阅读0次

    ◆ 发布&订阅
    ◆ 一对多

    应用场景:
    ◆ 点咖啡,点好之后坐等被叫
    ◆ 网页事件绑定
    ◆ Promise
    ◆ jQuery callbacks
    ◆ nodejs自定义事件

    观察者模式符合的设计原则:
    ◆ 主题和观察者分离,不是主动触发而是被动监听,两者解耦
    ◆ 符合开放封闭原则

    1. 实现一个观察者

    image.png
    // 主题,接收状态变化,触发每个观察者
    class Subject {
        constructor() {
            this.state = 0
            this.observers = []
        }
        getState() {
            return this.state
        }
        setState(state) {
            this.state = state
            this.notifyAllObservers()
        }
        attach(observer) {
            this.observers.push(observer)
        }
        notifyAllObservers() {
            this.observers.forEach(observer => {
                observer.update()
            })
        }
    }
    
    // 观察者,等待被触发
    class Observer {
        constructor(name, subject) {
            this.name = name
            this.subject = subject
            this.subject.attach(this)
        }
        update() {
            console.log(`${this.name} update, state: ${this.subject.getState()}`)
        }
    }
    
    // 测试代码
    let s = new Subject()
    let o1 = new Observer('o1', s)
    let o2 = new Observer('o2', s)
    let o3 = new Observer('o3', s)
    
    s.setState(1)
    s.setState(2)
    s.setState(3)
    

    2. 观察者的应用

    2.1 网页事件绑定

    $('#btn1').click(function () {
      console.log(1)
    })
    $('#btn1') .click(function () {
      console.log(2)
    })
    $('#btn1').click(function () {
      console.log(3)
    })
    // 1, 2, 3
    

    2.2 promise.then

    var src =' '
    var result = loadImg(src)
    result.then(function (img) {
      console.log('width', img.width)
      return img
    }).then(function (img) {
      console.log('height', img.height)
    })
    

    2.3 jQuery callbacks

    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') // fn1 gogogo fn2 gogogo fn3 gogogo
    callbacks.fire('fire') // fng fire fn2 fire fn3 fire
    

    2.4 node自定义事件

    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事件
    emitter.emit('some')
    
    // 传递参数
    const EventEmitter = require('events').EventEmitter
    const emitter = new EventEmitter()
    emitter.on('sbowName', name => {
      console. log('event occured', name)
    })
    emitter.emit('sbowName', 'zhangsan')
    

    继承node中的观察者模式

    const EventEmitter = require('events').EventEmitter
    // 在自己的类中继承EventEmitter的观察者模式
    class Dog extends EventEmitter {
      constructor(name) {
        super()
        this.name = name
      }
    }
    var simon = new Dog('simon')
    simon.on( 'bark', function () {
      console.log(this.name, 'barked')
    })
    setInterval(() => {
      simon.emit('bark')
    }, 500)
    

    node中的处理流文件也是观察者模式

    var fs = require('fs')
    var readStream = fs.createReadStream('./data/file1.txt') // 读取文件的 Stream
    
    var length = 0
    readStream.on('data', function(chunk) {
      length += chunk.toString().length
    })
    readStream.on('end', function () {
      console.log(length)
    ))
    
    var readline = require('readline');
    var fs = require('fs')
    var rl = readline.createInterface({
      input: fs.createReadStream('./data/file1.txt')
    });
    var lineNum = 0
    rl.on('line', function(line){
      lineNum++
    });
    rl.on('close', function() {
    console.log('lineNum' , lineNum)
    });
    

    node读取请求参数

    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()
        })
      }
    }
    
    image.png

    相关文章

      网友评论

          本文标题:观察者模式

          本文链接:https://www.haomeiwen.com/subject/aeseuctx.html