В чем разница между $ evalAsync и $ timeout в AngularJS?

мы использовали AngularJS в течение некоторого времени, и обнаружили необходимость использовать$ таймаут время от времени (кажется, обычно для запуска плагина jQuery).

Недавно яЯ пытался получить лучшее и более глубокое понимание цикла дайджеста, и я столкнулся с$ evalAsync функция.

Кажется, что эта функция дает аналогичные результаты$timeoutтолько ты неЗадержка. Каждый раз, когда ямы использовали$timeout это было с задержкой 0, так что теперь ямне интересно, если бы я использовал$evalAsync вместо.

Есть ли принципиальные различия между ними? Какие случаи вы бы использовали один над другим? Я'Я хотел бы получить лучшее представление о том, когда использовать какой.

Ответы на вопрос(2)

Решение Вопроса

Я недавно ответил по существу на этот вопрос здесь:https://stackoverflow.com/a/17239084/215945 (Этот ответ связан с некоторыми обменами Github с Миско.)

Подвести итоги:

если код ставится в очередь с помощью$ evalAsync из директивыдолжно бежатьпосле DOM манипулировал Angular, нодо браузер отображаетесли код ставится в очередь с помощью$ evalAsync от контроллерадолжно бежатьдо DOM манипулировал Angular (и до того, как браузер рендерится) - редко вы этого хотитеесли код ставится в очередь с помощью$ таймаутдолжно бежатьпосле DOM манипулировал Angular, ипосле браузер рендерится (что может вызвать мерцание в некоторых случаях)
 thorn̈30 мар. 2015 г., 21:05
да этонеужели неясно, что?из директивы " а также "из контроллера " значит здесь
 Jakub Hlavatý30 янв. 2017 г., 17:59
Отличный ответ! Это явно указано где-то в документации (моя проблема была решена с помощью $ timeout (0), поэтому я 'мне это особенно интересно)? Самый близкий я нашелdocs.angularjs.org/guide/scope, но не так явно, как ямне нравится :-)
 dnc25325 июн. 2013 г., 19:58
Спасибо за объяснение. Одна вещь, которую яЯ не уверен, что понимаю, хотя. Почему это имеет значение, если вывызываете $ evalAsync из контроллера или директивы? AsyncQueue не 'Не зная, было ли оно зарегистрировано из контроллера или директивы, он просто ставит его в очередь в текущей области видимости. Имеет ли это отношение к тому, когда вещи работают в контроллере против контроллера? Я просто хочу понять эту часть.
 Max Koretskyi aka Wizard11 авг. 2015 г., 19:49
@MarkRajcok, не могли бы вы уточнить здесь:если код ставится в очередь с использованием $ evalAsync из директивы, он должен выполняться после того, как Angular манипулирует DOM - должен ли он работать после того, как DOM был манипулирован этой директивой или другими директивами?
 Mark Rajcok25 июн. 2013 г., 21:26
@ dnc253, у меня нетЯ посмотрел на угловой код, поэтому я нене знаю ответа на ваш (хороший) вопрос. Надеюсь, кто-то еще может прокомментировать.
 SimplGy25 июл. 2014 г., 20:24
делает "из директивы " имею в виду "из функции связывания директивы "? Или это относится к поведению при выполнении из метода link или controller директивы?

Для тех, кто строит сложные приложения, имейте в виду, что на ваш выбор влияет производительность. Кроме того, я хотел бы дополнить ответ Марка более подробной технической информацией:

$ Таймаут (обратный вызов) будет ожидать выполнения текущего цикла дайджеста (то есть угловое обновление всей модели и DOM), затем выполнит обратный вызов - потенциально влияющий на угловую модель - затем запустит полный$apply в корне $ scope, и все заново.

$ EvalAsync (обратный вызов)с другой стороны, добавит обратный вызов в текущий или следующий цикл дайджеста. Это означает, что вы находитесь в цикле дайджеста (например, в функции, вызываемой из некоторогоng-click директива), это ничего не будет ждать, код будет выполнен сразу же. Если вы находитесь в асинхронном вызове, например,setTimeout, новый цикл дайджеста ($apply) будет срабатывать.

Так что с точки зрения производительности всегда лучше позвонить$evalAsync, если только вам не важно, чтобы представление обновлялось до выполнения вашего кода, например, если вам нужен доступ к некоторому атрибуту DOm, например, ширина элементов и тому подобное.

Если вы хотите узнать больше о различиях между $ timeout, $ evalAsync, $ digest, $ apply, я предлагаю вам прочитать мой ответ на этот другой вопрос:https://stackoverflow.com/a/23102223/1501926

Также не забудьте прочитатьдокументация:

$ EvalAsync не дает никаких гарантий относительно того, когда выражение будет выполнено, только то, что:

он будет выполняться после функции, которая запланировала оценку (предпочтительно до рендеринга DOM).по крайней мере один цикл $ digest будет выполнен после выполнения выражения.

Замечания:если эта функция вызывается вне цикла $ digest, будет запланирован новый цикл $ digest, Однако рекомендуется всегда вызывать код, который меняет модель, из вызова $ apply. Это включает в себя код, оцененный с помощью $ evalAsync.

 floribon18 сент. 2015 г., 02:18
@SridharChidurala, потому что DOM ("HTML») обновляется во время цикла дайджеста, вам нужно подождать, пока это будет сделано, прежде чем вы сможете прочитать предложения. Однако это не рекомендуется Angular, вы должны прочитатьx напрямую, а не из DOM, так что вы нене нужно ничего ждать. Кроме того, вы должны лучше использоватьng-style с CSS, а не устаревшимwidth имущество. Если вам нужна дополнительная помощь, пожалуйста, откройте новый вопрос на StackOverflow.
 Sridhar Chidurala18 сент. 2015 г., 01:02
Можете ли вы объяснить, почему $ timeout необходим, если мне нужен доступ к некоторому атрибуту DOM. Позволять'скажи, если у меня есть <ширина стола = "{{Х}} ">  Безразлично»т нг-биндФункция наблюдения обновляет атрибут dom в памяти, насколько я понимаю, у нее не будет возможности перерисовать представление до завершения цикла дайджеста.

Ваш ответ на вопрос