web-dev-qa-db-fra.com

Quel avantage y at-il à utiliser $ timeout dans AngularJS au lieu de window.setTimeout?

J'ai eu une suggestion pour implémenter un délai d'attente comme ceci:

  $timeout(function() {

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

  }, 2000);
};

Quelqu'un peut-il me dire quelle est la raison/avantage d'utiliser cela plutôt que d'utiliser setTimeout?

50
Samantha J T Star

En termes simples, $timeout Fait référence à angularjs lorsque setTimeout - à JavaScript.

Si vous pensez toujours utiliser setTimeout, vous devez donc appeler $scope.$apply() après

Comme note de côté

Je vous suggère de lire How do I “think in AngularJS” if I have a jQuery background? poster

et AngularJS: use $timeout, not setTimeout

Exemple 1: $ timeout

   $scope.timeInMs = 0;

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

Exemple 2: setTimeout (même logique)

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

Démo Fiddle


$ timeout renvoie également une promesse

[~ # ~] js [~ # ~]

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

[~ # ~] html [~ # ~]

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

$ timeout déclenche également le cycle de digestion

Considérez que nous avons un code de partie 3d (pas AngularJS) comme le plugin Cloudinary qui télécharge un fichier et nous renvoie un rappel de taux de pourcentage de "progression".

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

Nous voulons mettre à jour notre interface utilisateur aka $scope.file = file_;

Donc vide$timeout Fait le travail pour nous, il va déclencher le cycle de digestion et $scope.file Mis à jour par la partie 3d sera restitué dans l'interface graphique

64
Maxim Shoustin
  1. Il encapsule automatiquement votre rappel dans un bloc try/catch et vous permet de gérer les erreurs dans le service $ exceptionHandler: http://docs.angularjs.org/api/ng.$exceptionHandler
  2. Il retourne une promesse et a donc tendance à interagir mieux avec un code basé sur une promesse que l'approche traditionnelle par rappel. Lorsque votre rappel est renvoyé, la valeur renvoyée est utilisée pour résoudre la promesse.
20
ksimons

AngularJS modifie le flux JavaScript normal en fournissant sa propre boucle de traitement des événements. Cela divise le JavaScript en contexte d'exécution classique et AngularJS. Seules les opérations appliquées dans le contexte d'exécution AngularJS bénéficieront de la liaison de données AngularJS, du traitement des exceptions, de la surveillance des propriétés, etc.

En utilisant le service AngularJS $ timeout, le setTimeout encapsulé sera exécuté dans le contexte d'exécution AngularJS.

Pour plus d'informations, voir

1
georgeawg