Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Change the way $rootScope.$broadcast works internally #8461

Closed
@mcasimir

Description

@mcasimir

Hi, $rootScope.$broadcast/$scope.$on is almost perfect. It make us able to use $scope.$on for global events, this is perfect since we can handle local and global events the same way and it takes care of deleting listener (freeing memory) for us when $scope is destroyed.

Compared to it $rootScope.$emit/$rootScope.$on is faster but requires us to manually clear the callback to avoid leaking memory in listener.

$rootScope.$broadcast on the contrary is a little slow, cause it traverses all active scopes to find listeners to be triggered. Is it really necessary?

Why can't we solve the same problem in a different way?

Let's try to use a map in $rootScope:

Something like:

$rootScope.
evtScopesMap = {
   evt: {scope1ref: true, scope2ref: true}
}

Listening:

function $on(evt, cb) {
// ...
$rootScope.
evtScopesMap[evt] = thisScope;
}

Broadcasting:

function broadcast(evt) {
  Object.keys(this.evtScopesMap[evt]).forEach(function(scope){
    // Iterate scope.$$listeners and $emit;
  })
}

Cleaning up

scope.destroy = function(){
   // Iterate scope.$$listeners
   // forEach event this scope is bound to:

   delete $rootScope.evtScopesMap[evt][thisScope];
}

This should make $broadcast time constant in finding scopes at a small cost of a having an hashmap with scope references in $rootScope (cost in memory is linear to active scopes count).

I apologize if I misunderstood something here.

Thank you anyway

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions