我想定期重新运行一些取决于从服务器*检索的数据的方法。但是,我也想缓存那些数据,只打一次服务器。
如果是jQuery,我会做类似
的事情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() {...}
}
但是,d3的XHR函数似乎将async
参数硬编码为true。所以我发现自己做了类似
if (data != undefined) doSomething(data);
else {
d3.json(..., function(data) {
data = processData(data);
doSomething(data);
}
}
1)还有哪些其他设计用于缓存和决定是否进行AJAX调用?特别是在d3。
2)在doSomethingComplex
函数中定义draw
(以避免传入大量参数)似乎很懒惰。传递每个变量有什么好处?
*我的具体情况是在窗口调整大小时重绘d3条形图(我不喜欢viewBox
和preserveAspectRatio
处理文本大小调整的方式)。我很乐意听到重新调整大小的其他建议,但我对上述设计的建议感兴趣
答案 0 :(得分:2)
我觉得你不应该对使用闭合装置感到不舒服。 顺便说一句,我喜欢你的第二个代码示例,而不是第一个带有“sync”代码的代码示例。有可能 对于不习惯闭合的人来说似乎更直接,但这只是习惯性的问题。
除了“品味”之外还有什么能让你对第二个例子感到不舒服吗?
答案 1 :(得分:2)
你的第二个例子是更好的方法。使用sync: true
进行Ajax调用会使其同步,并且无法完成制作AJAX(记住 A 代表AJAX)调用的全部目的。
只要在平局中调用doSomethingComplex
是好还是坏,在不考虑整个设计的整体水平的情况下回答是一件棘手的事情。从表面上看,它违反了SRP,但是,使用JavaScript,有时这样做可以使整个代码流更合乎逻辑,更容易理解。在有意义的时候,我倾向于用教条主义来换取实用主义。
我想尝试重构代码,以便它不需要在绘制中调用doSomethingComplex
,看看是否更有意义。一般来说,单个函数执行的任务越少,测试和维护代码就越容易,不要忘记错误的可能性越小。
要减少传递所需的变量数,您始终可以将它们包装在一个对象中:
var state = {
foo: ...,
bar: ...
...
};
doSomethingComplex(state);
通过这样传递状态,你也可以避免关闭相关的副作用。不是说关闭总是很糟糕,但如果你能设法减少一件事,为什么不这样做呢?
同样,所有这些都取决于事物如何适应更大的图片,并使用这些点作为指导。没有银弹。