角度$广播和$昂贵吗?

Nat*_*ins 6 javascript events broadcast javascript-events angularjs

我被告知使用角度事件可能很昂贵(我一直无法验证这一点)

对工厂或服务进行任何调用$broadcast$on应该"包装"以注入相应的组件以保持性能?

同样,我宁愿$on直接使用并直接监听被触发的事件,而不是创建一个工厂,它本质上只是在收到事件时注册要调用的函数 - 让我们称之为调度程序.

请注意,听到'some-event'不仅仅是一个组件(指令),还会有各种组件监听此事件.

示例调度员:

angular.module('app').factory('dispatcher', ['$rootScope', function ($rootScope) {

    var registeredFns = [ ];

    $rootScope.$on('some-event', function (evt, msg) { 
        _.each(registeredFns, function (fn) {
            fn.apply(null, msg);
        });
    });

    return {
        onSomeEvent: function (fn) {
            registeredFns.push(fn);
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

并将它注入我需要它的地方 - 也许是一个指令,也许是一个无关紧要的控制器.

Cha*_*son 8

它们一点都不贵......但是如果它们被滥用(如同生活中的其他任何东西一样 - 它们可能很昂贵 - 这听起来像是一个好笑话的开始!)

了解这里实际发生的事情非常重要,而且代码实际上非常简单.如果你调用$ emit(),它只会for()在已注册的侦听器数组中执行循环并调用每个侦听器.它在您首次调用它的范围内执行此操作,然后向上"向上"每个父项,直到它达到$ rootScope.

有一些额外的代码可以处理像stopPropagation这样的东西,但除此之外就是这样.

$ broadcast做了类似的事情,但方向相反:它为()循环执行此操作,然后遍历每个范围.这是一个非常重要的区别,因为如果你做了一个$rootScope.$broadcast()并且你有很多ngRepeats和指令浮出水面,你可能会做比你预期更多的工作 - 即使这些范围都没有听取这个事件,Angular仍然有通过他们所有来解决这个问题.

如果你想在jsPerf或类似的地方做最快的测试,你最快的用例就是使用$rootScope.$emit()$rootScope.$on().这将为您提供基本消息传递的单范围测试,您可以从那里开始.