发布-订阅

在发布/订阅模式中,订阅者和发布者并不需要关心对方的状态,订阅者只管订阅事件并注册回调、发布者只管发布事件,其余一切交给调度中心来调度,从而能实现解耦。

首先要实现一个 Event 类,它应该含有一个收集回调函数的对象,和提供三个基础方法:on(订阅)、 emit(发布)、 off(注销)。

// event.js

class Event {
    /**
     * on 方法把订阅者所想要订阅的事件及相应的回调函数记录在 Event 对象的 _cbs 属性中
     */
    on (event, fn) {
        if (typeof fn != "function") {
            console.error('fn must be a function')
            return
        }
        
        this._cbs = this._cbs || {}
        ;(this._cbs[event] = this._cbs[event] || []).push(fn)
    }


    /**
     * emit 方法接受一个事件名称参数,在 Event 对象的 _cbs 属性中取出对应的数组,并逐个执行里面的回调函数
     */
    emit (event) {
        this._cbs = this._cbs || {}
        var callbacks = this._cbs[event], args

        if (callbacks) {
            callbacks = callbacks.slice(0)
            args = [].slice.call(arguments, 1)
            for (var i = 0, len = callbacks.length; i < len; i++) {
                callbacks[i].apply(null, args)
            }
        }
    }



    /**
     * off 方法接受事件名称和当初注册的回调函数作参数,在 Event 对象的 _cbs 属性中删除对应的回调函数。
     */
    off (event, fn) {
        this._cbs = this._cbs || {}

        // all
        if (!arguments.length) {
            this._cbs = {}
            return
        }

        var callbacks = this._cbs[event]
        if (!callbacks) return

        // remove all handlers
        if (arguments.length === 1) {
            delete this._cbs[event]
            return 
        }

        // remove specific handler
        var cb
        for (var i = 0, len = callbacks.length; i < len; i++) {
            cb = callbacks[i]
            if (cb === fn || cb.fn === fn) {
                callbacks.splice(i, 1)
                break
            }
        }
        return
    }    
}

使用方法:


订阅 “publishHandle” 事件

import event from './event.js'

event.on('publish',this.publishHandle.bind(this))

publishHandle: function(value) {
     ...
},
 ...


发布 “publishHandle” 事件

import event from './event.js'

function() {
    ... 
    event.emit('publish', value)
},

注销事件

import event from './event.js'

function(){
     // remove all
     event.off()
     // remove all callbacks
     event.off('publish')
     // remove specific callbacks
     event.off('publish', this.publishHandle)
}

 

引自 微信小程序跨页面通信解决思路

 

posted @ 2019-07-25 17:32  晨の风  阅读(171)  评论(0编辑  收藏  举报