In AngularJS we have a function $apply() which is a part of $scope object. The $apply() function accepts a function as its parameter. This function which is passed to the $apply() contains the code where the changes are being done to the models which are used in our AngularJS application. For AngularJS application to know about the changes in the models, we have to do this i.e. write the code inside a function and call $scope.$apply() passing the function name as the parameter.
After the function has finished executing, AngularJS checks for any changes to the models. To do so, it calls a function called $digest() which is a part of $rootScope object.
NOTE: $rootScope is a global object created by AngularJS whenever any AngularJS application is bootstrapped.
When AngularJS calls the $rootScope.$digest() function and if any change in the value of a model is found, it calls the appropriate listener function for the model. Each listener function for a model may have a separate logic to what should be done if a model value changes.
After the $rootScope.$digest() has checked the models for any changes and all the appropriate listeners have been called, the $digest() loop runs once again and checks for any changes that might have been made to the models by the listeners itself. If any change on the value of model is found, then again the listener functions are called and $digest() function runs again to check for any further changes. If no changes are executed then $digest() loop stops. The $digest() loop will keep running if there are some changes in the models value. It will run maximum up to 10 times.