AngularJS에서 $ evalAsync와 $ timeout의 차이점은 무엇입니까?


180

나는 잠시 동안 AngularJS를 사용 하고 있었고 가끔 $ timeout 을 가끔씩 사용해야한다는 것을 알았습니다 (보통 jQuery 플러그인을 초기화하는 것으로 보입니다).

최근에, 나는 다이제스트 사이클에 대해 더 잘 이해하려고 노력하고 있으며 $ evalAsync 함수를 발견했습니다.

그 함수는와 비슷한 결과를 생성하는 것처럼 보이지만 $timeout지연 시키지는 않습니다. 내가 사용할 때마다 $timeout0의 지연이 있었으므로 이제 $evalAsync대신 사용해야했는지 궁금합니다 .

둘 사이에 근본적인 차이점이 있습니까? 어떤 경우를 다른 것으로 사용 하시겠습니까? 언제 어느 것을 사용해야하는지 더 잘 알고 싶습니다.

답변:


263

나는 최근 에이 질문에 본질적으로 대답했습니다 : https : //.com/a/17239084/215945 (이 답변은 Misko와의 일부 github 교환에 대한 링크입니다.)

요약:

  • 코드를 사용하여 대기중인 경우 지시문에서 $ evalAsync를 , 그것을 실행해야합니다 DOM을이 각도에 의해 조작되었지만, 전에 브라우저가 렌더링
  • 코드를 사용하여 대기중인 경우 컨트롤러에서 $ evalAsync를 , 그것을 실행해야합니다 전에 DOM을이 각도에 의해 (브라우저가 렌더링되기 전에) 조작되었다 - 거의 당신이 원하는하지 않는다
  • 코드를 사용하여 대기하는 경우 $ 제한 시간을 , 그것을 실행해야합니다 DOM을이 각도에 의해 조작되었고, 후에 브라우저 렌더링 (어떤 경우에는 깜박임이 발생할 수 있음)

15
설명 감사합니다. 그래도 잘 모르겠습니다. 컨트롤러 또는 지시문에서 $ evalAsync를 호출하는 경우 왜 차이가 있습니까? asyncQueue는 컨트롤러 또는 지시문에서 등록되었는지 여부를 알지 못하고 현재 범위에서 대기합니다. 컨트롤러에서 컨트롤러로 물건을 실행할 때와 관련이 있습니까? 나는 단지 그 부분을 이해하고 싶다.
dnc253

@ dnc253, Angular 코드를 보지 않았으므로 귀하의 (좋은) 질문에 대한 답을 모릅니다. 다른 누군가가 댓글을 달 수 있기를 바랍니다.
Mark Rajcok

15
"지시문에서"는 "지시문의 링크 기능에서"를 의미합니까? 아니면 지시문의 링크 또는 컨트롤러 메소드에서 실행될 때 동작이 사실입니까?
SimplGy

5
"지시서에서"와 "제어기에서"가 여기에서 무슨 뜻인지는 확실하지 않습니다
thorn̈

1
@MarkRajcok, 여기에서 명확히 할 수 있습니까 : 지시문에서 $ evalAsync를 사용하여 코드가 대기열에 있으면 DOM이 Angular에 의해 조작 된 후에 실행되어야합니다-DOM 이이 지시문에 의해 또는 다른 지시문에 의해 조작 된 후에 실행되어야합니까?
Max Koretskyi

59

복잡한 응용 프로그램을 구축하는 경우 선택한 성능에 영향을 미칩니다. 또한 기술적 인 세부 사항으로 Mark 답변을 작성하고 싶습니다.

  • $ timeout (callback) 은 현재 다이제스트주기가 완료 될 때까지 기다립니다 (즉, 모든 모델 및 DOM의 각도 업데이트). 그러면 콜백 (각도 모델에 영향을 줄 수 있음)을 실행 한 다음 $apply루트 $ scope에서 전체를 시작하고 다시 시작합니다. 모두.

  • 반면 $ evalAsync (callback) 은 콜백을 현재 또는 다음 다이제스트 사이클에 추가합니다. 즉, 다이제스트주기 (예 : 일부 ng-click지시문 에서 호출 된 함수 )에 있으면 아무것도 기다리지 않고 코드가 즉시 실행됩니다. 비동기 호출 (예 : a) 내에있는 경우 setTimeout새 다이제스트주기 ( $apply)가 트리거됩니다.

따라서 성능 측면에서는 $evalAsync코드를 실행하기 전에 뷰를 최신 상태로 유지하는 것이 중요하지 않은 경우 (예를 들어 요소 너비 등과 같은 일부 DOm 속성에 액세스해야하는 경우가 아니라면 ) 항상 호출하는 것이 좋습니다 .

: 당신이 $ 제한 시간의 차이, $ evalAsync, $, $ 적용, 소화에 대한 자세한 내용을 원하는 경우에 나는 다른 질문에 대한 내 대답 읽는 당신을 초대합니다 https://stackoverflow.com/a/23102223/1501926을

또한 설명서 를 읽으십시오 .

$ evalAsync는 표현식이 언제 실행 될지 보장하지 않습니다.

  • 평가를 예약 한 기능 후에 (바람직하게는 DOM 렌더링 전에) 실행됩니다.
  • 식 실행 후 적어도 하나의 $ 다이제스트주기가 수행됩니다.

참고 : 이 기능을 $ digest주기 외부에서 호출하면 새로운 $ digest주기가 예약 됩니다. 그러나 $ apply 호출 내에서 모델을 변경하는 코드를 항상 호출하는 것이 좋습니다. 여기에는 $ evalAsync를 통해 평가 된 코드가 포함됩니다.


DOM 속성에 액세스해야하는 경우 $ timeout이 필요한 이유를 설명해 주시겠습니까? <table width = "{{x}}"> ng-bind의 watch 함수가 메모리의 dom 속성을 업데이트하지 않으면 다이제스트 사이클이 종료 될 때까지 뷰를 다시 페인트 할 기회가 없다는 것을 이해합니다.
Sridhar Chidurala

2
@SridharChidurala 다이제스트 사이클 동안 DOM ( "HTML")이 업데이트되기 때문에 수정을 읽기 전에 DOM이 완료 될 때까지 기다려야합니다. 그러나 Angular에서는 권장 x하지 않으므로 DOM이 아닌 스코프에서 직접 읽어야 하므로 아무것도 기다릴 필요가 없습니다. 또한 더 ng-style이상 사용되지 않는 width속성 보다는 CSS를 사용 하는 것이 좋습니다 . 도움이 더 필요한 경우 StackOverflow에 대한 새 질문을여십시오.
floribon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.