I've been using AngularJS for a little while now, and have found the need to use $timeout every once in a while (Seems to usually be to init a jQuery plugin).
Recently, I've been trying to get a better and more in-depth understanding of the digest cycle, and I came across $evalAsync function.
It seems like that function produces similar results to $timeout
, only you don't give it delay. Every time I've used $timeout
it has been with a delay of 0, so now I'm wondering if I should have used $evalAsync
instead.
Are there any fundamental differences between the two? What cases would you use one over the other? I'd like to get a better feeling of when to use which one.
This '$timeout' service of AngularJS is functionally similar to the 'window. setTimeout' object of vanilla JavaScript. This service allows the developer to set some time delay before the execution of the function.
$evalAsync([expression], [locals]);Executes the expression on the current scope at a later point in time. The $evalAsync makes no guarantees as to when the expression will be executed, only that: it will execute after the function that scheduled the evaluation (preferably before DOM rendering).
The $timeout service can be used to call another JavaScript function after a given time delay. The $timeout service only schedules a single call to the function. For repeated calling of a function, see $interval later in this text.
I recently answered essentially this question here: https://stackoverflow.com/a/17239084/215945 (That answer links to some github exchanges with Misko.)
To summarize:
For those building complex applications, be aware that there is a performance impact on your choice. Also, I would like to complete Mark answer with more technical details:
$timeout(callback) will wait for the current digest cycle to be done (i.e. angular update all model and the DOM), then it will execute its callback - potentially affecting angular model - then launch a full $apply
on the root $scope, and redigest everything.
$evalAsync(callback), on the other hand, will add the callback to the current, or next, digest cycle. Which means if you are within a digest cycle (for instance in a function called from some ng-click
directive), this will not wait for anything, the code will be executed right away. If you are within an asynchronous call, for instance a setTimeout
, a new digest cycle ($apply
) will be triggered.
So in terms of performances it is always better to call $evalAsync
, unless it is important for you that the view is up to date before executing your code, for instance if you need acces to some DOm attribute such as elements width and the like.
If you want more details about the distinction between $timeout, $evalAsync, $digest, $apply, I invite you to read my answer on that other question: https://stackoverflow.com/a/23102223/1501926
Also be sure to read the documentation:
The $evalAsync makes no guarantees as to when the expression will be executed, only that:
- it will execute after the function that scheduled the evaluation (preferably before DOM rendering).
- at least one $digest cycle will be performed after expression execution.
Note: if this function is called outside of a $digest cycle, a new $digest cycle will be scheduled. However, it is encouraged to always call code that changes the model from within an $apply call. That includes code evaluated via $evalAsync.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With