В чем преимущество использования $timeout в AngularJS вместо window.setTimeout?

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

  $timeout(function() {

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

  }, 2000);
};

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


person Samantha J T Star    schedule 26.10.2013    source источник


Ответы (3)


Проще говоря, $timeout относится к angularjs, а setTimeout — к JavaScript.

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

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

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

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

Пример 1: $ тайм-аут

   $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 также запускает цикл дайджеста

Учтите, что у нас есть сторонний код (не 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);         
            })

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

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

person Maxim Shoustin    schedule 26.10.2013
comment
setTimeout() определенно не относится к jQuery (это стандартный JavaScript). - person ComFreek; 26.10.2013
comment
да, извините, я забыл, когда в последний раз использовал setTimeout. Спасибо за исправление - person Maxim Shoustin; 26.10.2013
comment
$timeout также возвращает обещание: этот пример кажется действительно полезным! - person Sam Vloeberghs; 11.12.2014

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

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

При использовании сервиса $timeout AngularJS обернутый setTimeout будет выполняться в контексте выполнения AngularJS.

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

person georgeawg    schedule 02.08.2018