Какое преимущество дает использование $timeout в AngularJS вместо window.setTimeout?

У меня было предложение реализовать такой таймаут:

  $timeout(function() {

    // Loadind done here - Show message for 3 more seconds.
    $timeout(function() {
      $scope.showMessage = false;
    }, 3000);

  }, 2000);
};

Может ли кто-нибудь сказать мне, в чем причина / преимущество использования этого, а не использования setTimeout?

Решение

Основными словами $timeout относится к angularjs, а setTimeout - к JavaScript.

Если вы все еще думаете использовать setTimeout, то вам нужно вызвать $scope.$apply() после

В качестве примечания

Я предлагаю вам прочитать Как мне "думать в AngularJS", если у меня есть опыт работы с jQuery? пост

и AngularJS: используйте $timeout, а не setTimeout

Пример 1: $timeout.

   $scope.timeInMs = 0;

    var countUp = function() {
        $scope.timeInMs+= 500;
        $timeout(countUp, 500);
    }    
    $timeout(countUp, 500); 

Пример 2: setTimeout (та же логика)

 $scope.timeInMs_old = 0;

    var countUp_old = function() {
        $scope.timeInMs_old+= 500;        
        setTimeout(function () {
        $scope.$apply(countUp_old);
    }, 500);
    }

    setTimeout(function () {
        $scope.$apply(countUp_old);
    }, 500);

Demo [Fiddle][3]


$timeout также возвращает обещание

JS

function promiseCtrl($scope, $timeout) { 
 $scope.result = $timeout(function({ 
 return "Ready!"; 
 }, 1000); 
}

HTML

<div ng-controller="promiseCtrl"> 
 {{result || "Preparing…"}}
</div> 

$timeout также запускает цикл дайджеста

Предположим, что у нас есть сторонний код (не AngularJS), например, плагин Cloudinary, который загружает некоторый файл и возвращает нам 'progress' процентный коллбэк.

     // .....
     .on("cloudinaryprogress",
           function (e, data) {
               var name = data.files[0].name;
               var file_ = $scope.file || {};
               file_.progress = Math.round((data.loaded * 100.0) / data.total);

                $timeout(function(){
                     $scope.file = file_;
                }, 0);         
            })

Мы хотим обновить наш UI aka $scope.file = file_;.

Так что пустой $timeout сделает за нас эту работу, он запустит цикл дайджеста и $scope.file, обновленный 3d-стороной, будет повторно отображен в GUI

Комментарии (3)
  1. Он автоматически оборачивает ваш обратный вызов в блок try/catch и позволяет обрабатывать ошибки в сервисе $exceptionHandler: http://docs.angularjs.org/api/ng.$exceptionHandler
  2. Он возвращает обещание и поэтому лучше взаимодействует с другим кодом, основанным на обещаниях, чем традиционный подход с обратным вызовом. Когда ваш обратный вызов возвращается, возвращаемое значение используется для разрешения обещания.
Комментарии (0)

AngularJS изменяет обычный поток JavaScript, предоставляя свой собственный цикл обработки событий. Это разделяет JavaScript на классический и контекст выполнения AngularJS. Только те операции, которые применяются в контексте выполнения AngularJS, получат преимущества от привязки данных AngularJS, обработки исключений, просмотра свойств и т. д.

Благодаря использованию сервиса AngularJS $timeout, обернутая функция setTimeout будет выполняться в контексте выполнения AngularJS.

Для получения дополнительной информации см.

Комментарии (0)