Skip to content

Instantly share code, notes, and snippets.

@racsoraul
Last active April 14, 2018 23:12
Show Gist options
  • Save racsoraul/419fc46ea1ecd07da04b1de5c65349a1 to your computer and use it in GitHub Desktop.
Save racsoraul/419fc46ea1ecd07da04b1de5c65349a1 to your computer and use it in GitHub Desktop.
Prueba de concepto para almacenamiento de caché en funciones asíncronas "puras".
/**
* Simula asincronía en una función. Toma una función
* síncrona y la devuelve "asíncrona".
*
* @param {Number} [ms=1000] Milisegundos de espera.
*/
const fakeAsync = (ms = 1000) => f => (...params) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
try {
resolve(f(...params))
} catch (error) {
reject(error)
}
}, ms)
})
}
/**
* Genera caché al resultado de una función asíncrona. Es necesario que sea
* una función pura para obtener el resultado esperado.
*
* Por defecto, el primer parámetro se convierte en el identificador para
* guardar caché, sino, puede especificarse un identificador, pasándolo
* como parámetro en la segunda función devuelta.
*
* El identificador personalizado (key) es especialmente útil si en la lista
* de los parámetros de la función el primer parámetro no será un string.
*
* @param {Function} f Función asíncrona a la cual se le desea generar caché.
*/
const cacheFunction = f => {
let cache = {}
return (...params) =>
/**
* Define el identificador único para el guardado del caché.
*
* @param {String} [key=params[0]] Identificador para almacenar caché.
*/
(key = params[0]) => {
if (cache[key]) {
return Promise.resolve(cache[key])
} else {
return f(...params)
.then(result => {
cache[key] = result
return result
})
.catch(console.error)
}
}
}
/**
* Recibe la zona territorial, y retorna los departamentos
* que le conforman según la organización territorial
* de El Salvador.
*
* @param {String} zona Zona territorial de El Salvador.
*/
const getDepartments = (zona) => {
switch (zona) {
case "occidental":
return ["Ahuachapán", "Santa Ana", "Sonsonate"]
case "oriental":
return ["Usulután", "San Miguel", "Morazán", "La Unión"]
case "central":
return ["La Libertad", "Chalatenango", "Cuscatlán", "San Salvador"]
case "paracentral":
return ["La Paz", "Cabañas", "San Vicente"]
default:
return []
}
}
// Vuelve asíncrona la función síncrona pasada.
const getDepartmentsAsync = fakeAsync()(getDepartments)
// Retorna una función con la capacidad de guardar caché.
const getDepartmentsAsyncCached = cacheFunction(getDepartmentsAsync)
// Uso final: f(...params)(key=params[0]):Promise
getDepartmentsAsyncCached("central")()
.then(console.log)
.catch(console.error)
// Luego de la ejecución anterior de "getDepartmentsAsyncCached", la próxima vez que se
// ejecute con el mismo parámetro, la respuesta será extraída del caché. Y así sucesivamente,
// con distintos parámetros.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment