web-dev-qa-db-fra.com

Angularjs promet un chaînage de rejet

J'ai besoin de créer des promesses enchaînées:

var deferred = $q.defer();
$timeout(function() {
    deferred.reject({result: 'errror'});
}, 3000);
deferred.promise.then(angular.noop, function errorHandler(result) {
    //some actions
    return result;
}).then(function successCallback(result) {
    console.log('what do I do here?');
    return result;
}, function errorCallback(result) {
   $scope.result= result;
   return result;
});

Si je mets un errorCallback dans le premier then, le second then sera résolu et son successCallback sera appelé. Mais si je supprime errorHandler, la deuxième promesse sera rejetée.

Selon Angular JS docs, la seule façon de propager le rejet est de renvoyer $q.reject(); et cela ne semble pas évident, surtout parce que je dois injecter le service $q Même s'il n'est pas nécessaire;

Cela peut également être fait en lançant une exception dans errorHandler, mais il écrit une trace d'exception sur la console, ce n'est pas bon.

Existe-t-il une autre option pour le faire de manière claire? Et quelle en est la raison? Pourquoi est-ce fait? Dans quel cas, le comportement actuel peut être utile?

29
just-boris

Et quelle est la raison pour laquelle cela est fait. Dans quel cas, le comportement actuel peut être utile?

Il peut être utile lorsque dans errorHandler vous pouvez essayer de réparer l'état d'erreur et de résoudre la promesse d'une manière ou d'une autre.

var retriesCount = 0;

function doWork()
{
    return $http.post('url')
        .then(function(response){
            // check success-property of returned data
            if(response.data.success)
                // just unwrap data from response, may be do some other manipulations
                return response.data;
            else
                // reject with error
                return $q.reject('some error occured');
        })
        .catch(function(reason){
            if(retriesCount++ < 3)
                // some error, let me try to recover myself once again
                return doWork();
            else
                // mission failed... finally reject
                return $q.reject(reason);
        });
}


doWork().then(console.log, console.error);
68
ant

Tard à la fête, mais comme je suis ici;

Je préfère utiliser le $http erreur pour sa gestion des erreurs native, plutôt que de retourner un succès via un 200 et un état d'erreur dans la réponse.

impression 400 ou 500 les erreurs dans la console ne sont pas un problème, si vous déboguez, vous les voyez, sinon vous ne les voyez pas.

angular.module('workModule', [])

// work provider handles all api calls to get work
.service('workProvider', ['$http', '$q', function($http, $q) {

    var endpoint = '/api/v1/work/';

    this.Get = function(){
        // return the promise, and use 404, 500, etc for errors on the server
        return $http.get(endpoint);
    };

}])

.controller('workController', ['workProvider', function('workProvider'){

    workProvider.Get().then(
        function(response){ // success
            console.log(response.data);
        },
        function(response){ // error
             console.log(response.data);           
        }
    )

}])
5
Matthew.Lothian