简体   繁体   中英

How to be explicit in resolving deferred promise in angular $q?

If I have something in my service like

myServiceMethod: function(){
    $http.get(myUrl)
        .success(function(result){$q.defer().resolve(result);})
        .error(function(error){$q.defer().resolve(error);});

    return $q.defer().promise;
}

and in my controller

myService.myServiceMethod()
    .then(function(result){})
    .then(function(error){});

is there a way to be explicit in the name space? Because it seems like the deferred promises can get messy if you start nesting deferred resolve. For example

myServiceMethod: function(){
    $http.get(myUrl)
        .success(
            function(result){
                if(result){
                    $q.defer().resolve(result);
                }else{
                    $q.defer().resolve(myCustomresult);
                }
        })
        .error(function(error){$q.defer().resolve(error);});

    return $q.defer().promise;
}

You are creating too many deferred objects and the one being returned is not what you are resolving or rejecting

Just return the $http which itself returns a promise. what you are trying to do is considered an anti-pattern

myServiceMethod: function(){
    // return the `$http` promise
    return $http.get(myUrl)
        .then(function(result){return result.data);})
         // either catch it here or catch in controller
        .catch(function(error){ alert('Error')});
}

Controller

myService.myServiceMethod()
    .then(function(result){})
    .catch(function(error){});

Every time you call $q.defer() you are creating a new promise, which isn't the right thing to do.

The $http.get method itself returns a promise, so unless you are doing something else that needs to run asynchronously, you do not need to use $q

For arguments sake, you can do this:

myServiceMethod: function() {
 var myPromise =  $q.defer();
 $http.get(myUrl).success(function(result){
    if(result)
      myPromise.resolve(result);
    else
     myPromise.reject(result);
  });
return myPromise.promise;
}

Could be much shorter:

Service

myServiceMethod: function () {
    return $http.get(myUrl).then(function (response) {
        return response.data || myCustomResult; // default result if API returned nothing
    });
}

Controller

myService.myServiceMethod()
    .then(function (result) { /* do something ... */ })
    .catch(function (error) { /* handle error ... */ });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM