Подтвердить что ты не робот

Как часто выполняется цикл дайджеста AngularJS?

При обсуждении преимуществ AngularJS двусторонняя привязка данных часто рекламируется как основное преимущество Angular по сравнению с другими структурами JS. Копаем глубже, документация предполагает, что этот процесс выполняется посредством грязной проверки, а не посредством событийных мер. Во-первых, кажется, что цикл дайджеста работает путем периодического срабатывания метода в фоновом режиме, проверяя все $watch es в течение каждого цикла. Однако, читая далее, кажется, что цикл digest фактически инициируется rootScope.digest(), который, в свою очередь, запускается $.apply, который, в свою очередь, инициируется событием (!), Таким как событие onClick, вызванное через ng-click.

Но как это может быть? Я думал, что Angular не использует прослушиватели изменений. Итак, как работает дайджест-цикл? Может ли Angular автоматически запускать цикл дайджеста внутри или цикл сбора данных, вызванный событиями? Если цикл дайджеста запускается автоматически, как часто он выполняется?


Некоторые пояснения:

  • Я не спрашиваю о том, как цикл digest запускается при ручном привязке к изменениям. В этом случае, если вы хотите принудительно создать цикл дайджеста, вы можете сделать это, вызвав $.apply()
  • Я также не спрашиваю, как часто цикл цикла digest выполняется в ответ на пользовательские события. Например, если ng-model находится в поле ввода, Angular начнет цикл дайджеста, когда пользователь начнет вводить текст. Запутанная часть заключается в том, что для того, чтобы знать, что пользователь печатает, не использует ли Angular где-то на основе событийKeyUp?
  • Я уже знаю, что существует предел в 10 циклов максимум за цикл дайджеста. Мой вопрос меньше о количестве циклов в цикле дайджеста, а о количестве циклов дайджеста, которые работают, скажем, в секунду.
  • Бонусные вопросы: как цикл digest связан с циклом событий JavaScript? Периодически выполняется цикл событий JS в фоновом режиме? Является ли цикл дайджеста тем же самым, что и цикл событий, но только в контексте Angular? Это совершенно разные идеи?
4b9b3361

Ответ 1

Angular запускаются дайджесты - они не происходят через опрос.

Код выполняется после завершения кода, angular запускает дайджест.

Пример:

 element.on('click', function() {
     $scope.$apply(function() { 
         // do some code here, after this, $digest cycle will be triggered
     });
 });

Angular также запускает $digest после фазы компиляции/ссылки:

Compile > Link > Digest

А как много циклов дайджестов срабатывает? Это зависит от того, как скоро переменные сферы будут стабилизированы. Обычно для определения этого требуется как минимум 2 цикла.

Ответ 2

Короткий прямой ответ на главный вопрос: "НЕТ", angular автоматически не запускает цикл дайджеста.

TL; DR ответ:

Цикл дайджеста предназначен для запуска грязной проверки моделей POJO, связанных с экземплярами области angular, поэтому ее нужно запускать только тогда, когда модель может быть изменена. В одностраничном веб-приложении, запущенном внутри браузера, следующие действия/события могут привести к изменению модели.

  • События DOM
  • Ответы XHR, вызывающие обратные вызовы
  • Изменение местоположения браузера
  • Таймеры (setTimout, setInterval), вызывающие обратные вызовы

Соответственно, angular цикл дайджеста триггера, например

  • директивы ввода + ngModel, ngClick, ngMouseOver и т.д.
  • $http и $resource
  • $location
  • $таймаут

Попробуйте ответить на эти бонусные вопросы из моего понимания:

  • Директива ngModel часто используется с директивами ввода angular (текст, выбор и т.д.) вместе, а латнеры будут прослушивать события "изменения" и вызывать $setViewValue API, открытый из ngModelController, чтобы синхронизировать предыдущее значение dom. Во время процесса синхронизации ngModelController будет запускать цикл дайджеста.
  • Цикл дайджеста отличается от цикла событий JS, позже это концепция времени выполнения JS (проверка большой визуализированной сессии https://www.youtube.com/watch?v=8aGhZQkoFbQ), которые запускаются от очереди событий и автоматически удалять из очереди потребляемое событие, но цикл дайджест никогда не удаляет часы из своего списка просмотра, если вы явно не выберете.
  • количество циклов дайджеста в секунду зависит от эффективности всех обратных вызовов часов, выполняемых в цикле. Если какой-то плохой код занял одну секунду, то этот цикл дайджеста будет стоить более 1 секунды.

Итак, некоторые ключевые методы для предотвращения ошибок angular -

  • Обратный вызов должен быть закодирован как можно более простой/эффективный, например, отсоединить сложный алгоритм кода, например, рабочие потоки
  • Упреждающее удаление часов, если они больше не используются
  • Предпочитает вызывать $scope. $digest() вместо $scope. $apply(), если применимо, $digest() выполняет только часть дерева областей и обеспечивает соответствие моделей, связанных с поддеревом, для просмотра. Но $apply() будет работать против всего дерева областей, он будет перебирать больше часов.

Ответ 3

Я считаю, что это то, что происходит. AngularJS сделал разумное предположение, что изменения модели происходят только при взаимодействии с пользователем. Эти взаимодействия могут произойти из-за

  • Активность мыши (перемещение, щелчок и т.д.)
  • Активность клавиатуры (клавиша, клавиша и т.д.)

Директивы AngularJS для соответствующих событий завершают выполнение выражения в $scope. $apply, как показано @pixelbits в его примере. Это приводит к циклу дайджест.

Есть и другие события, в которых AngularJS запускает цикл дайджеста. $timeout и услуга $interval - это два таких примера. Код, завернутый в эти службы, также приводит к циклу дайджеста для запуска. Возможно, некоторые другие события\службы, которые могут вызвать циклы дайджеста, но это основные из них.

Именно по этой причине изменения модели вне контекста Angular не обновляют часы и привязки. Поэтому нужно явно называть $scope. $Apply. Мы делаем это все время при интеграции с плагинами jQuery.