Quiero volver a ejecutar periódicamente algún método que dependa de los datos recuperados del servidor *. Sin embargo, también quiero almacenar en caché esos datos y solo llegar al servidor una vez.
Si fuera jQuery, haría algo como
function draw() {
var data = undefined;
// Pre-data retrieval code
var foo, bar, alpha, beta, gamma, etc.
...
if (data == undefined) {
$.ajax({
...
async: false, // IMPORTANT PART
success: function(data) {
data = processData(data);
}
});
}
doSomethingComplex(data);
// Defined within to inherit scope
// i.e., don't want to pass in foo, bar, alpha, beta, gamma, etc.
function doSomethingComplex() {...}
}
Sin embargo, las funciones XHR de d3 parecen codificar el parámetro async
en verdadero. Entonces me encuentro haciendo algo como
if (data != undefined) doSomething(data);
else {
d3.json(..., function(data) {
data = processData(data);
doSomething(data);
}
}
1) ¿Qué otros diseños hay para almacenar en caché y decidir si realizar una llamada AJAX? Específicamente en d3.
2) La definición de doSomethingComplex
dentro de la función draw
(para evitar pasar muchos parámetros) parece vago. ¿Alguna ventaja de pasar cada variable?
* Mi caso específico es volver a dibujar un gráfico de barras d3 en el cambio de tamaño de la ventana (no me gustó cómo viewBox
y preserveAspectRatio
manejaron el cambio de tamaño del texto). Con mucho gusto escucharé otras sugerencias para volver a dibujar en el cambio de tamaño, pero estoy interesado en sugerencias para el diseño anterior
2 respuestas
Su segundo ejemplo es la mejor manera. Hacer una llamada Ajax con sync: true
lo hace síncrono y anula el propósito de hacer una llamada AJAX (recuerda lo que significa la llamada A en AJAX).
En cuanto a llamar a doSomethingComplex
dentro del sorteo es bueno o malo, es algo difícil de responder sin mirar a un nivel holístico en todo su diseño. En la superficie, viola SRP, pero luego, con JavaScript, a veces hacerlo puede hacer que todo flujo de código lógico y más fácil de seguir. Tiendo a cambiar el dogmatismo a favor del pragmatismo cuando tiene sentido.
Diría que intente refactorizar el código para que no sea necesario llamar a doSomethingComplex
en el sorteo y ver si eso tiene más sentido. En general, cuantas menos tareas realice una sola función, más fácil será probar y mantener el código, sin olvidar la menor posibilidad de que tenga errores.
Para reducir la cantidad de variables requeridas para pasar, siempre puede envolverlas en un solo objeto:
var state = {
foo: ...,
bar: ...
...
};
doSomethingComplex(state);
Al pasar un estado como este, también evitará los efectos secundarios relacionados con el cierre. No digo que los cierres siempre sean malos, pero si puedes tener una cosa menos de qué preocuparte, ¿por qué no hacer eso?
Una vez más, todo esto depende de cómo encajan las cosas en la imagen más grande y usa estos puntos como una luz de guía. No hay bala de plata.
No creo que deba sentirse incómodo con el uso de cierres. Por cierto, me gusta su segundo ejemplo de código más que el primero con el código de "sincronización". Puede parecer más directo a alguien que no está acostumbrado a los cierres, pero esto es solo una cuestión de acostumbrarse.
¿Hay algo al lado del "gusto" que te haga sentir incómodo con el segundo ejemplo?
Preguntas relacionadas
Nuevas preguntas
javascript
Para preguntas sobre la programación en ECMAScript (JavaScript / JS) y sus diversos dialectos / implementaciones (excepto ActionScript). Incluya todas las etiquetas relevantes en su pregunta; por ejemplo, [node.js], [jquery], [json], etc.