Angularjs pubsub vs $broadcast

Я читал о событии, проходящем в Angularjs, и я не уверен, что использование $broadcast - хорошая идея.

Блоги вроде этого одного защитника привыкают к $, даже несмотря на то, что он "чувствует себя излишним".

Мое замешательство заключается в том, что реализация использует сквозной проход по глубине и просматривает подписчиков, что делает скорость ваших событий зависимой от вашей древовидной структуры. Вот код из этого в 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/$? Или есть ли какая-либо польза от использования более традиционного pubsub?

Сообщите мне, если я не буду достаточно ясным с моим вопросом и благодарю за ваше время.

Ответ 1

Я не думаю, что вы что-то пропускаете. Вы успешно описали плюсы и минусы каждого подхода.

Подход $broadcast/$on не требует от вас отмены подписки, но он не очень эффективен, поскольку он транслирует все области. Он также имеет очень низкий барьер для входа. Вам не нужно вводить какие-либо услуги, вам не нужно их создавать. Они транслируются для всех, поэтому это более простой подход.

Подход pub/sub гораздо более прямой. Только подписчики получают события, поэтому они не попадают в каждую область в системе, чтобы заставить ее работать. Однако это сложнее, потому что вам нужно написать свою службу с обработчиками обратного вызова, и вы должны помнить о том, чтобы отказаться от подписки. На мой взгляд, запоминание отказа от подписки довольно велико. Если вы не получите это правильно, вы получите утечки памяти. И вы не узнаете об этом, пока это не проблема через 3 месяца.

Я вижу, почему встроенный подход $broadcast.

Ответ 2

Я смотрел на эту же проблему. В частности, как разрешать услуги для трансляции и подписки на события без доступа к $rootScope (плохо по нескольким причинам). Я использовал очень отличную реализацию js-сигналов отсюда: http://millermedeiros.github.io/js-signals/ и завернул его в службу angular.

github gist здесь: https://gist.github.com/anonymous/b552c7fafa77427e6d06