你能解决一个angularjs的承诺,然后再返回它吗?
我正在尝试编写一个返回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); });
问题是,callback没有执行预先解决的承诺。 这是一个合法的事情吗? 有没有更好的方法来处理这种情况?
简短的回答:是的,你可以在返回之前解决一个AngularJS的承诺,它会像你期望的那样行事。
从JB Nizet的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); } );
我希望它可以帮助别人。 我没有发现其他答案很清楚。
如何简单地在Angular中返回预先解决的承诺
解决的承诺:
return $q.when( someValue ); // angular 1.2+ return $q.resolve( someValue ); // angular 1.4+, alias to `when` to match ES6
拒绝承诺:
return $q.reject( someValue );
这是我通常如何做,如果我想实际caching数组或对象中的数据
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
您忘记初始化caching元素
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]; } }
我喜欢用工厂从我的资源中获取数据。
.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.whatever来暴露它,或者做它在上下文中正确的东西
似乎工作正常。 但我有点新的angular度。 *error handling主要是为了清晰