Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS $http.post responses activated much faster if periodic $rootScope.$digest in effect

In our very large and quite complex AngularJS application, I noticed (by accident!) that a line like this in my main module setup...

application.run(function($rootScope) {
    window.setInterval( () => { $rootScope.$digest(); }, 1000);
});

...has significant positive impact, in the activation time of our $http.post requests.

A small part of our code that deterministically reproduces the behaviour is this:

// In the partial
<button ... ng-click="buttonHandler" ...>

// In the controller
$scope.buttonHandler = function() {
    $http.post(....).success( function() { console.log("Activated"); })
}
  • We associate a button's ng-click handler with invocation of one of our web services.
  • The web service itself responds within 30ms (according to Chrome developer tools).
  • However, the code inside the .success handler is executed after 1.75 - 2.3 seconds (and only then is the message "Activated" displayed in the console).

However, when we put the Eternal rootScope $digest Hack (TM) in place, the activation occurs in less than a second! :-)

I can only guess that the rootScope $digest somehow 'triggers' the actual invocation of the .success handler, and since the webservice itself responds in 30ms, the activation time depends on when the button press happens to fall in the 1 second period of the hack's setInterval.

I am not saying that this is a recommended practise - but i was very surprised to see it happen. Note that there are no console errors logged or any other mischief reported anywhere in my assertive checks - the code works fine with or without the hack, but with significantly improved performance when the hack is in place.

Any idea what is going on?

like image 247
ttsiodras Avatar asked Nov 10 '22 13:11

ttsiodras


1 Answers

Promises in Angular queue up a callback with $rootScope.$evalAsync(callback).

  1. The callback checks to see whether the promise has been resolved/rejected.
  2. $evalAsync schedules the task to run after the next digest cycle is complete.

Therefore, if you're preemptively asking for a digest cycle, your promise may be resolved quicker.

Source: https://github.com/angular/angular.js/blob/master/src/ng/q.js#L175

like image 57
Gabe Avatar answered Nov 15 '22 13:11

Gabe