javascript - templatecache - angularjs http post example with parameters
Almacenamiento en caché de un objeto de promesa en el servicio AngularJS (2)
Quiero implementar una carga dinámica de un recurso estático en AngularJS utilizando Promises. El problema: tengo un par de componentes en la página que pueden (o no, depende de cuáles se muestran, por lo tanto, dinámicos) tener que obtener un recurso estático del servidor. Una vez cargado, puede almacenarse en caché para toda la vida útil de la aplicación.
Implementé este mecanismo, pero soy nuevo en Angular and Promises, y quiero asegurarme de que este sea un enfoque de solución correcto.
var data = null;
var deferredLoadData = null;
function loadDataPromise() {
if (deferredLoadData !== null)
return deferredLoadData.promise;
deferredLoadData = $q.defer();
$http.get("data.json").then(function (res) {
data = res.data;
return deferredLoadData.resolve();
}, function (res) {
return deferredLoadData.reject();
});
return deferredLoadData.promise;
}
Por lo tanto, solo se realiza una solicitud y todas las próximas llamadas a loadDataPromise () obtienen la primera promesa hecha. Parece que funciona para solicitarlo en el progreso o uno que ya terminó hace algún tiempo.
Pero, ¿es una buena solución guardar en caché las promesas?
¿Es este el enfoque correcto?
Sí. El uso de la memoisation en las funciones que regresan promete una técnica común para evitar la ejecución repetida de tareas asincrónicas (y generalmente costosas). La promesa facilita el almacenamiento en caché porque no es necesario distinguir entre las operaciones en curso y las terminadas, ambas se representan como (la misma) promesa para el valor del resultado.
¿Es esta la solución correcta?
No. Esa variable de data
global y la resolución con undefined
no es cómo se pretende que funcionen las promesas. En cambio, ¡cumple la promesa con los data
resultados! También hace que la codificación sea mucho más fácil:
var dataPromise = null;
function getData() {
if (dataPromise == null)
dataPromise = $http.get("data.json").then(function (res) {
return res.data;
});
return dataPromise;
}
Luego, en lugar de loadDataPromise().then(function() { /* use global */ data })
es simplemente getData().then(function(data) { … })
.
Para mejorar aún más el patrón, es posible que desee ocultar dataPromise
en un alcance de cierre, y observe que necesitará una búsqueda de promesas diferentes cuando getData
toma un parámetro (como la url).
Para esta tarea, creé un servicio llamado defer-cache-service que elimina todo este código de la placa de la caldera. Se escribió en Typescript, pero puede tomar el archivo compilado js. Código fuente de Github.
Ejemplo:
function loadCached() {
return deferCacheService.getDeferred(''cacke.key1'', function () {
return $http.get("data.json");
});
}
y consumir
loadCached().then(function(data) {
//...
});
Una cosa importante para notar es que, digamos dos o más partes que llamen al mismo loadDataPromise y al mismo tiempo, debe agregar este control
if (defer && defer.promise.$$state.status === 0) {
return defer.promise;
}
de lo contrario, se realizarán llamadas duplicadas para el back-end.