promises promesas example angularjs promise

angularjs - promesas - promise angular 6



¿Puedes resolver una promesa de angularjs antes de devolverla? (5)

Intento escribir una función que devuelva una promesa. Pero hay ocasiones en que la información solicitada está disponible de inmediato. Quiero envolverlo en una promesa para que el consumidor no tenga que tomar una decisión.

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}); } }

Y úsalo así:

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

El problema es que la devolución de llamada no se ejecuta para la promesa resuelta previamente. ¿Es esto algo legítimo que hacer? ¿Hay una mejor manera de manejar esta situación?


Cómo devolver simplemente una promesa resuelta en Angular

Promesa resuelta:

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

Promesa rechazada:

return $q.reject( someValue );


Así es como normalmente lo hago si quiero almacenar en caché los datos en una matriz u objeto

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


Me gusta usar una fábrica para obtener los datos de mi recurso algo así como.

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

A continuación, exponga mi modelo en el servicio de esta manera aquí

.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); }); }; }]);

Entonces, mis controladores pueden incluirlo y exponerlo, o hacer lo que corresponde es justo en su contexto simplemente haciendo referencia al servicio inyectado.

Parece que funciona bien. Pero soy un poco nuevo en angular. * el manejo de errores se omite principalmente para mayor claridad


Olvidaste inicializar el elemento de caché

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]; } }


Respuesta corta: Sí, puede resolver una promesa de AngularJS antes de devolverla, y se comportará como era de esperar.

Desde plnkr.co/edit/OGO8T2M1fE3Mrgj2oozj?p=preview pero refactorizado para trabajar dentro del contexto de lo que se pidió originalmente (es decir, una llamada de función al servicio) y realmente en el sitio.

Dentro del servicio ...

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; }

Dentro del controlador ...

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

Espero que esto ayude a alguien. No encontré las otras respuestas muy claras.