AngularJS promise chain

2019-05-02 06:21发布

问题:

I have my application that should open a popup ask a confirmation at the user, then make an ajax cal and close the popup.
I tried to do it using a chain of promise (I've already used it, and I remember that it should work in this way), but it seems to block after the call toreservationService.confirm($scope.object);. Now it is a fake service implemented with a setTimeout and $q just to return a promise (in future it will make the ajax call). Is this a valid code or I didn't undestood how promise works?
For the popup I choose AngularUI and the code is this:

 reservationService.book($scope.object, day)
        .then(function(){
            var dialogOpts = {/* dialog options omitted*/}
            return $dialog.dialog(dialogOpts).open();

        })
        .then(function(result){
            console.log('confirmed? ', result);
            if (result){
                //After this line it doesn't do nothing, also if the promise is resolved 
                return reservationService.confirm($scope.object);
            }
        })
        .then(function(){
            //this function is never executed
            $scope.$emit('object:detail',{object: $scope.object});
        });

reservationService:

function confirm(){
     var deferred = $q.defer();
     setTimeout(function(){
          console.log('Confirming');
          deferred.resolve(true)
     }, 500);
     return deferred.promise;
}

SOLVED change setTimeout with $timeout angular's service

回答1:

Used $timeout instead of setTimeout 'cause it works togheter at the angular scope, forcing the digest phase (or use $scope.apply() inside the setTimeout).



回答2:

Can you try

//skipping the first then
.then(function(result){
            var deferred = $q.defer();
            console.log('confirmed? ', result);
            if (result){
                //After this line it doesn't do nothing, also if the promise is resolved 
                return deferred.resolve(reservationService.confirm($scope.object));
            }
            deferred.resolve();
            return deferred.promise;
        })
.then(function(){
                //this function is never executed
                $scope.$emit('object:detail',{object: $scope.object});
            });

For chaining then, the last then success or failure function should return a promise. As the $q documentation mentions

then(successCallback, errorCallback) – regardless of when the promise was or will be resolved or rejected, then calls one of the success or error callbacks asynchronously as soon as the result is available. The callbacks are called with a single argument: the result or rejection reason.

This method returns a new promise which is resolved or rejected via the return value of the successCallback or errorCallback.