【问题标题】:Angularjs pubsub vs $broadcastAngularjs pubsub vs $broadcast
【发布时间】:2014-03-05 12:04:39
【问题描述】:

我一直在阅读 Angularjs 中的事件传递,但我不相信使用 $broadcast 是个好主意。

one 之类的博客提倡习惯使用 $on,即使它“感觉有点矫枉过正”。

我的困惑是,该实现使用深度优先遍历范围并寻找订阅者,这使得事件的速度取决于您的树结构。 以下是 Angular 中的一些代码:

// Insanity Warning: scope depth-first traversal
// yes, this code is a bit crazy, but it works and we have tests to prove it!
// this piece should be kept in sync with the traversal in $digest
if (!(next = (current.$$childHead || (current !== target && current.$$nextSibling)))) {
   while(current !== target && !(next = current.$$nextSibling)) {
     current = current.$parent;
   }
}

此外,您似乎可以使用这些方法破解依赖注入。

替代方案只是一个缓存事件类型和回调的服务,并直接调用它们。这需要您清理订阅以避免泄漏。

我的问题是,关于 $broadcast/$on 范式的动机有什么我遗漏的吗?或者与更传统的 pubsub 相比,使用它有什么好处?

如果我的问题不够清楚,请告诉我,感谢您抽出宝贵时间。

【问题讨论】:

  • 这是一个很好的问题,谢谢你的提问。

标签: javascript angularjs publish-subscribe


【解决方案1】:

我认为你没有遗漏任何东西。您已成功概述了每种方法的优缺点。

$broadcast/$on 方法不需要您取消订阅,但它的效率并不高,因为它会广播到所有范围。它的进入门槛也很低。您不需要注入任何服务,也不需要创建它们。他们向所有人广播,所以这是一种更简单的方法。

发布/订阅方式更为直接。只有订阅者才能获得事件,因此它不会进入系统中的每个范围以使其工作。然而,它更复杂,因为您需要使用回调处理程序编写服务,并且您必须记住取消订阅。在我看来,记住退订是相当大的。如果你不正确,你会得到内存泄漏。而且你不会知道它,直到它在 3 个月内出现问题。

我明白为什么内置方法是$broadcast

【讨论】:

  • 不知道有没有办法自动退订。如果发布/订阅模型与 Angular 集成,您可以在 $destroy 上自动取消订阅。控制器和指令通常对应一个范围,并且可以以漂亮的1::1 方式取消订阅它的销毁。服务/工厂/提供者的自动化不太明显,但通常它们无论如何都是单例的。
  • 你可以做类似的事情,但是你会将范围传递给服务。这似乎不是最佳做法。
  • 就我个人而言,将$rootScope 传递到服务中并没有什么大问题。我理解内心的反应,但我内心的实用主义者会说“为什么不呢?”。
  • 传递$rootScope 是不够的。这允许您在 $rootScope 被销毁时销毁所有 pub subs,但您需要传入单独的 $scope 对象。不这样做的原因是服务应该与层次结构无关。在这种情况下,这样做仍然很安全,但我喜欢它作为一个坚定的规则。
  • $broadcast 不一定向所有人“广播”。它仅将事件发送到 Scope 的子作用域。 $rootScope.$broadcast 将发送给“每个人”,但控制器的 $scope.$broadcast 只会发送给包含在该控制器中的控制器和指令范围。
【解决方案2】:

我正在研究同样的问题。特别是如何允许服务在不访问 $rootScope 的情况下广播和订阅事件(由于某些原因很糟糕)。 我从这里使用了非常出色的 js-signals 实现: http://millermedeiros.github.io/js-signals/ 并将其包装成一个角度服务。

github 要点在这里:https://gist.github.com/anonymous/b552c7fafa77427e6d06

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-25
    • 2010-11-24
    • 2015-09-07
    • 2016-11-08
    • 1970-01-01
    • 2015-04-06
    • 2018-08-29
    • 1970-01-01
    相关资源
    最近更新 更多