首页 文章

你可以在返回之前解决angularjs的承诺吗?

提问于
浏览
118

我正在尝试编写一个返回promise的函数 . 但有时候请求的信息是立即可用的 . 我想将它包装在一个承诺中,以便消费者不需要做出决定 .

function getSomething(id) {
    if (Cache[id]) {
        var deferred = $q.defer();
        deferred.resolve(Cache[id]); // <-- Can I do this?
        return deferred.promise;
    } else {
        return $http.get('/someUrl', {id:id});
    }
}

并像这样使用它:

somethingService.getSomething(5).then(function(thing) {
    alert(thing);
});

问题是回调不会针对预解析的承诺执行 . 这是合法的事吗?有没有更好的方法来处理这种情况?

5 回答

  • 6

    Short answer: Yes, you can 在您返回之前解决AngularJS承诺,并且它将按照您的预期运行 .

    JB Nizet's Plunkr开始,但重构为在最初要求的内容(即函数调用服务)的上下文中工作,并且实际在现场 .

    服务内...

    function getSomething(id) {
        // There will always be a promise so always declare it.
        var deferred = $q.defer();
        if (Cache[id]) {
            // Resolve the deferred $q object before returning the promise
            deferred.resolve(Cache[id]); 
            return deferred.promise;
        } 
        // else- not in cache 
        $http.get('/someUrl', {id:id}).success(function(data){
            // Store your data or what ever.... 
            // Then resolve
            deferred.resolve(data);               
        }).error(function(data, status, headers, config) {
            deferred.reject("Error: request returned status " + status); 
        });
        return deferred.promise;
    
    }
    

    控制器内部....

    somethingService.getSomething(5).then(    
        function(thing) {     // On success
            alert(thing);
        },
        function(message) {   // On failure
            alert(message);
        }
    );
    

    我希望它对某人有帮助 . 我没有发现其他答案非常明确 .

  • 170

    如何在Angular 1.x中简单地返回预先解析的promise

    已解决的承诺:

    return $q.when( someValue );    // angular 1.2+
    return $q.resolve( someValue ); // angular 1.4+, alias to `when` to match ES6
    

    拒绝的承诺:

    return $q.reject( someValue );
    
  • 0

    如果我想在数组或对象中实际缓存数据,我通常会这样做

    app.factory('DataService', function($q, $http) {
      var cache = {};
      var service= {       
        getData: function(id, callback) {
          var deffered = $q.defer();
          if (cache[id]) {         
            deffered.resolve(cache[id])
          } else {            
            $http.get('data.json').then(function(res) {
              cache[id] = res.data;              
              deffered.resolve(cache[id])
            })
          }
          return deffered.promise.then(callback)
        }
      }
    
      return service
    
    })
    

    DEMO

  • 0

    您忘记初始化Cache元素

    function getSomething(id) {
        if (Cache[id]) {
            var deferred = $q.defer();
            deferred.resolve(Cache[id]); // <-- Can I do this?
            return deferred.promise;
        } else {
            Cache[id] = $http.get('/someUrl', {id:id});
            return Cache[id];
        }
    }
    
  • 94

    我喜欢使用工厂从我的资源中获取数据 .

    .factory("SweetFactory", [ "$http", "$q", "$resource", function( $http, $q, $resource ) {
        return $resource("/sweet/app", {}, {
            "put": {
                method: "PUT",
                isArray: false
            },"get": {
                method: "GET",
                isArray: false
            }
        });
    }]);
    

    然后在这里像这样在服务中公开我的模型

    .service("SweetService",  [ "$q", "$filter",  "$log", "SweetFactory",
        function ($q, $filter, $log, SweetFactory) {
    
            var service = this;
    
            //Object that may be exposed by a controller if desired update using get and put methods provided
            service.stuff={
                //all kinds of stuff
            };
    
            service.listOfStuff = [
                {value:"", text:"Please Select"},
                {value:"stuff", text:"stuff"}];
    
            service.getStuff = function () {
    
                var deferred = $q.defer();
    
              var promise = SweetFactory.get().$promise.then(
                    function (response) {
                        if (response.response.result.code !== "COOL_BABY") {
                            deferred.reject(response);
                        } else {
                            deferred.resolve(response);
                            console.log("stuff is got", service.alerts);
                            return deferred.promise;
                        }
    
                    }
                ).catch(
                    function (error) {
                        deferred.reject(error);
                        console.log("failed to get stuff");
                    }
                );
    
                promise.then(function(response){
                    //...do some stuff to sett your stuff maybe fancy it up
                    service.stuff.formattedStuff = $filter('stuffFormatter')(service.stuff);
    
                });
    
    
                return service.stuff;
            };
    
    
            service.putStuff = function () {
                console.log("putting stuff eh", service.stuff);
    
                //maybe do stuff to your stuff
    
                AlertsFactory.put(service.stuff).$promise.then(function (response) {
                    console.log("yep yep", response.response.code);
                    service.getStuff();
                }).catch(function (errorData) {
                    alert("Failed to update stuff" + errorData.response.code);
                });
    
            };
    
        }]);
    

    然后,我的控制器可以包含它并将其暴露或者仅仅通过引用注入的Service来执行它在其上下文中所做的事情 .

    似乎工作正常 . 但我对角度有点新意 . *为了清楚起见,错误处理大多被遗漏

相关问题