I recently answered essentially this question here: https://stackoverflow.com/a/17239084/215945
(That answer links to some github exchanges with Misko.)
To summarize:
- if code is queued using $evalAsync from a directive, it should run after the DOM has been manipulated by Angular, but before the browser renders
- if code is queued using $evalAsync from a controller, it should run before the DOM has been manipulated by Angular (and before the browser renders) — rarely do you want this
- if code is queued using $timeout, it should run after the DOM has been manipulated by Angular, and after the browser renders (which may cause flicker in some cases)