web-dev-qa-db-ger.com

Verwenden Sie Erfolg / Fehler / Endlich / Fang mit Versprechen in AngularJS

Ich benutze $http in AngularJs, und ich bin nicht sicher, wie ich das zurückgegebene Versprechen verwenden und mit Fehlern umgehen soll.

Ich habe diesen Code:

$http
    .get(url)
    .success(function(data) {
        // Handle data
    })
    .error(function(data, status) {
        // Handle HTTP error
    })
    .finally(function() {
        // Execute logic independent of success/error
    })
    .catch(function(error) {
        // Catch and handle exceptions from success/error/finally functions
    });

Ist das ein guter Weg, oder gibt es einen einfacheren Weg?

109
Joel

Versprechen sind eine Abstraktion über Anweisungen, die es uns ermöglichen, uns synchron mit asynchronem Code auszudrücken. Sie stellen eine Ausführung einer einmaligen Aufgabe dar.

Sie bieten auch eine Ausnahmebehandlung, genau wie normaler Code, den Sie von einem Versprechen zurückgeben oder werfen können.

Was Sie im synchronen Code wollen, ist:

try{
  try{
      var res = $http.getSync("url");
      res = someProcessingOf(res);
  } catch (e) {
      console.log("Got an error!",e);
      throw e; // rethrow to not marked as handled
  }
  // do more stuff with res
} catch (e){
     // handle errors in processing or in error.
}

Die versprochene Version ist sehr ähnlich:

$http.get("url").
then(someProcessingOf).
catch(function(e){
   console.log("got an error in initial processing",e);
   throw e; // rethrow to not marked as handled, 
            // in $q it's better to `return $q.reject(e)` here
}).then(function(res){
    // do more stuff
}).catch(function(e){
    // handle errors in processing or in error.
});
97

Vergessen Sie die Methoden success und error.

Beide Methoden wurden in angular 1.4. Grundsätzlich ist der Grund für die Abwertung, dass sie nicht verkettungsfähig sind . , sozusagen.

Mit dem folgenden Beispiel werde ich versuchen zu demonstrieren, was ich damit meine, dass success und error nicht verkettungsfähig sind ). Angenommen, wir rufen eine API auf, die ein Benutzerobjekt mit einer Adresse zurückgibt:

Benutzerobjekt:

{name: 'Igor', address: 'San Francisco'}

Aufruf der API:

$http.get('/user')
    .success(function (user) {
        return user.address;   <---  
    })                            |  // you might expect that 'obj' is equal to the
    .then(function (obj) {   ------  // address of the user, but it is NOT

        console.log(obj); // -> {name: 'Igor', address: 'San Francisco'}
    });
};

Was ist passiert?

Weil success und error das ursprüngliche Versprechen zurückgeben, dh dasjenige, das von $http.get, Das an den Callback des then übergebene Objekt ist das gesamte Benutzerobjekt , also das gleiche Eingabe in den vorhergehenden success Rückruf.

Wenn wir zwei then angekettet hätten, wäre dies weniger verwirrend gewesen:

$http.get('/user')
    .then(function (user) {
        return user.address;  
    })
    .then(function (obj) {  
        console.log(obj); // -> 'San Francisco'
    });
};
42

Ich denke, die vorherigen Antworten sind korrekt, aber hier ist ein anderes Beispiel (nur ein f.y.i, Erfolg () und Fehler () sind nach AngularJS veraltet Hauptseite :

$http
    .get('http://someendpoint/maybe/returns/JSON')
    .then(function(response) {
        return response.data;
    }).catch(function(e) {
        console.log('Error: ', e);
        throw e;
    }).finally(function() {
        console.log('This finally block');
    });
35
grepit

Welche Art von Granularität suchen Sie? Sie kommen in der Regel mit Folgendem aus:

$http.get(url).then(
  //success function
  function(results) {
    //do something w/results.data
  },
  //error function
  function(err) {
    //handle error
  }
);

Ich habe festgestellt, dass "endlich" und "fangen" besser dran sind, wenn mehrere Versprechen verkettet werden.

11
justin

In Angular $ http) wurde das Antwortobjekt für die Funktion success () und error () entpackt, sodass die Rückrufsignatur wie $ http (...) lautet. Success (function ( Daten, Status, Header, Konfiguration))

für then () werden Sie sich wahrscheinlich mit dem rohen Antwortobjekt befassen. wie im AngularJS $ http API-Dokument veröffentlicht

$http({
        url: $scope.url,
        method: $scope.method,
        cache: $templateCache
    })
    .success(function(data, status) {
        $scope.status = status;
        $scope.data = data;
    })
    .error(function(data, status) {
        $scope.data = data || 'Request failed';
        $scope.status = status;
    });

Das letzte .catch (...) wird erst benötigt, wenn in der vorherigen Versprechenskette ein neuer Fehler aufgetreten ist.

5
zd333