O. R. Mapper O. R. Mapper - 6 months ago 92
Javascript Question

Angular 2 equivalent for $timeout

I have to use (large amounts of) existing code in an Angular 2 environment. That code makes extensive use of the

service from AngularJS 1.x. As opposed to various other AngularJS 1.x services that are used in the code, I am having a hard time finding a information about an Angular 2 equivalent for the
$timeout
service.

The Angular docs do not seem to contain any mention of a service with
timeout
-something in its name. The article Upgrading from AngularJS does mention the scenario I am facing:


Maybe you want access to AngularJS's built-in services like
$location
or
$timeout
.


Unfortunately, the article does not actually explain how to access those particular services, as the subsequent example
HeroesService
assumes a service without any dependencies supplied by AngularJS 1.x.

Articles such as this one suggest using the native
setTimeout
function
does not live up to the capabilities of the
$timeout
services, either.

How can I reproduce the
$timeout
functionality in the Angular 2 environment?


EDIT: As has been noted in the answers, the drawbacks of the native
setTimeout
function are not relevant when using Angular 2. In that case, if I had the full
$q
from AngularJS 1.x, I could replicate the
$timeout
function roughly like this:

function $timeout(fn, delay) {
var result = $q.defer();
setTimeout(function () {
$q.when(fn()).then(function (v) {
result.resolve(v);
});
}, delay);
return result.promise;
}

Answer Source

Use setTimeout native function. There is no need to use special services in Angular anymore.

Articles such as this one suggest using the native setTimeout function does not live up to the capabilities of the $timeout services, either.

Why makes you say so? The main task of $timeout service was to start digest after the delayed function is executed. You can see it from the sources:

function $TimeoutProvider() {
  this.$get = ['$rootScope', '$browser', '$q', '$$q', '$exceptionHandler',
    function($rootScope,   $browser,   $q,   $$q,   $exceptionHandler) {

        timeoutId = $browser.defer(function() {
          try {
            deferred.resolve(fn.apply(null, args));
          } catch (e) {
          ...

          if (!skipApply) $rootScope.$apply();  <-------------------- here
        }, delay);

In Angular zone.js intercepts all async operations and starts change detection in Angular which is kind of enhanced version of digest.

If you need to replicate the $timeout, you can roughly do it like this:

function $timeout(fn, delay) {
    return new Promise((resolve, reject) => {
       setTimeout(function () {
           try {
               resolve(fn());
           } catch (e) {
               reject(e);
           }
       }, delay);
    })
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download