Utilizzo del timeout $ per normalizzare il tempo di risposta di una chiamata al servizio web (domanda sulle migliori pratiche)

1

Considera di avere una semplice, standard $http di richiesta per una API REST:

...
function makeCall() {
    var restURL = "http://my-rest-api/endpoint";
    return $http.get(restURL);
}
...

Se il tempo di esecuzione di questa chiamata varia per qualsiasi motivo (a volte ritorna immediatamente, altre volte impiega circa un secondo a e), qual è la procedura migliore per normalizzare il tempo di risposta per l'utente?

In passato, ho fatto cose del genere:

...
function makeCall() {
    var restURL = "http://my-rest-api/endpoint";
    return $http.get(restURL);
}

...

function myController($scope) {
    var promise = makeCall(); //make rest call
    $scope.waitMessage = true;
    $timeout(function() {
        //before resolving the promise, wait a certain number of ms, then
        //resolve and display data to user
        promise.then(function(response) {
            $scope.output = response.data;
            $scope.waitMessage = false;
        });
    }, 1000);
}

Questo è un tentativo di fare in modo che la richiesta impieghi una quantità di tempo fissa, indipendentemente dal fatto che sia stata restituita immediatamente o meno. Durante il tempo di ritardo, visualizzo un interstitial di qualche tipo che dice "Caricamento in corso, attendere ..." o simili, controllati da una variabile come $scope.waitMessage .

Qualche best practice per questo tipo di casi d'uso?

    
posta A n d r e w Ferguson 15.03.2015 - 17:41
fonte

1 risposta

1

Non sono sicuro che si tratti di una "best practice", ma il mio modo è di creare una direttiva che riduca le modifiche alle variabili, usando la funzione lodash / underscore throttle :

app.directive('throttle', function($window) {
  var WAIT_TIME = 750;

  return {
    scope: true,
    link: function(scope, element, attrs) {
      var name = attrs.throttle;

      function setValue(value) {
        // Shadow the value in the child scope
        scope[name] = value;

        // The leading edge of the _.throttle callback
        // is called within a digest, but later ones are not
        scope.$$phase || scope.$apply();
      }

      scope.$parent.$watch(name, $window._.throttle(setValue, WAIT_TIME));
    }
  };
});

Può essere usato per una semplice variabile di stato del testo per determinare cosa mostrare all'utente:

<div throttle="state">
  <div ng-if="state == 'loading'">Loading...</div>
  <div ng-if="state == 'loaded'">[Loaded template]</div>
</div>

Quindi, facendo riferimento al codice nella tua domanda, nel controller potresti avere qualcosa di simile:

$scope.state = 'loading';
makeCall().then(function(response) {
  $scope.output = response.data;
  $scope.state = 'loaded';
});

I vantaggi di fare questo anziché tramite $timeout s nel tuo controller o servizi:

  • Migliore separazione delle responsabilità. Il controller / servizi non hanno bisogno di sapere esattamente come / quando i dati verranno mostrati all'utente. Questo è solo nel template / direttiva.

  • Limitazione significa che hai impostato un tempo minimo per cui un determinato stato verrà mostrato all'utente. Se l'utente è già stato in tale stato per almeno quella volta, non ci sarà più tempo di attesa in più.

Originariamente l'ho postato sul mio blog all'indirizzo link

    
risposta data 15.04.2015 - 10:08
fonte

Leggi altre domande sui tag