Какое преимущество заключается в использовании $timeout в Angular JS вместо window.setTimeout?

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

  $timeout(function() {

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

  }, 2000);
};

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

Ответ 1

В основных словах $timeout относится к angularjs, когда setTimeout - к JavaScript.

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

В качестве дополнительной заметки

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

и 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);

Демо Fiddle


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

JS

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

HTML

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

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

Считаем, что у нас есть некоторый 3d-код (не AngularJS), такой как плагин Cloudinary, который загружает некоторый файл и возвращает нам обратный вызов процентной ставки "прогресс".

     // .....
     .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);         
            })

Мы хотим обновить наш пользовательский интерфейс aka $scope.file = file_;

Таким образом, пустой $timeout выполняет задание для нас, это вызовет цикл дайджест и $scope.file, обновленный третьей стороной, будет повторно отображаться в графическом интерфейсе

Ответ 2

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