JS简易实现eventBus

一、

源码

(function (exporter) {
    function isFunc(fn) { return typeof fn === "function" }
    function str(s) {
        if (s == null) {
            return null;
        }
        s = s.replace(/^\s+|\s+$/g, "");
        return s.length > 0 ? s.toLowerCase() : null;
    }

    function handler() {
        var fns = [];
        var datas = [];
        this.add = function (fn, data) {
            fns.push(fn);
            datas.push(data);
        }
        this.remove = function (fn) {
            var i = fns.indexOf(fn);
            if (i >= 0) {
                fns.splice(i, 1);
                datas.splice(i, 1);
            }
        }
        this.invoke = function (sender, data) {
            fns.forEach((fn, i) => {
                try {
                    fn(sender, data, datas[i])
                } catch (error) {
                    console.error(error);
                }
            });
        }
    }

    function eventBus() {
        var handers = {}
        this.on = function (eventName, fnOrData, fn) {
            eventName = str(eventName);
            if (eventName == null) {
                throw new Error("事件名无效");
            }
            if (!isFunc(fn)) {
                var temp = fn;
                fn = fnOrData;
                fnOrData = temp;
            }
            if (!isFunc(fn)) {
                throw new Error("必须提供事件函数");
            }
            var handle = handers[eventName];
            if (handle == null) {
                handle = new handler();
                handers[eventName] = handle;
            }
            handle.add(fn, fnOrData);
        }
        this.off = function (eventName, fn) {
            eventName = str(eventName);
            if (eventName == null) {
                return;
            }
            var handle = handers[eventName];
            if (handle != null) {
                if (fn == null) {
                    delete handers[eventName];
                } else {
                    handle.remove(fn);
                }
            }
        }
        this.fire = this.emit = this.trigger =
            function (eventName, sender, data) {
                eventName = str(eventName);
                if (eventName == null) {
                    return;
                }
                var handle = handers[eventName];
                if (handle != null) {
                    handle.invoke(sender, data);
                }
            }
        var bus = this;
        this.bindTo = function(obj){
            if(obj == null){
                throw new Error("obj is null");
            }
            for (const key in bus) {
                if (bus.hasOwnProperty(key) && key !== "bindTo") {
                    obj[key] = bus[key];
                }
            }
        }
    }
    var instance = new eventBus();
    instance.bindTo(eventBus);
    exporter(eventBus);
})(c => window.eventBus = c)

二、

绑定
eventBus.on(eventName, function[, obj]);

eventBus.on("data_completed", function (sender, data, obj) {
    console.log({ sender, data, sign: obj.sign });
}, { sign: "F6243749AFF04C0581E1DD178A0B737A" });

触发
eventBus.emit(eventName[, sender][, data]);
eventBus.trigger(eventName[, sender][, data]);
eventBus.fire(eventName[, sender][, data]);

eventBus.emit("Data_Completed", window, [1,2,3,4,5,6]);

四、

多次绑定

var f2 = function (sender, data, obj) {
    console.log({ sender, data, sign: obj.sign });
}
eventBus.on("data_completed", f2 , { sign: "722F9C19C9704412B93216BD70F2AE52" });
eventBus.emit("Data_Completed", window, [1,2,3,4,5,6]);

四、

解绑、清空
eventBus.off(eventName[, function]);

eventBus.off("Data_Completed", f2);
eventBus.emit("Data_Completed", window, [1,2,3,4,5,6]);
eventBus.off("Data_Completed");
eventBus.emit("Data_Completed", window, [1,2,3,4,5,6]);

五、

初始化一个新的

var myEventBus = new eventBus();

推荐阅读更多精彩内容

  • JQuery的源码看过吗?能不能简单概况一下它的实现原理? jQuery.fn的init方法返回的this指的是什...
    过往的雨阅读 839评论 0 10
  • "use strict";function _classCallCheck(e,t){if(!(e instanc...
    久些阅读 950评论 0 1
  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 5,158评论 2 17
  • 南京新街口,南京最繁华的CBD,中国著名的商业中心,拥有近百年历史,被誉为“中华第一商圈”。但是今天我们不说别的,...
    逸管家app阅读 147评论 1 0
  • 居家生活阅读 37评论 0 0