异步数据检索和缓存

时间:2014-09-02 14:10:15

标签: javascript caching d3.js

我想定期重新运行一些取决于从服务器*检索的数据的方法。但是,我也想缓存那些数据,只打一次服务器。

如果是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条形图(我不喜欢viewBoxpreserveAspectRatio处理文本大小调整的方式)。我很乐意听到重新调整大小的其他建议,但我对上述设计的建议感兴趣

2 个答案:

答案 0 :(得分:2)

我觉得你不应该对使用闭合装置感到不舒服。 顺便说一句,我喜欢你的第二个代码示例,而不是第一个带有“sync”代码的代码示例。有可能 对于不习惯闭合的人来说似乎更直接,但这只是习惯性的问题。

除了“品味”之外还有什么能让你对第二个例子感到不舒服吗?

答案 1 :(得分:2)

你的第二个例子是更好的方法。使用sync: true进行Ajax调用会使其同步,并且无法完成制作AJAX(记住 A 代表AJAX)调用的全部目的。

只要在平局中调用doSomethingComplex是好还是坏,在不考虑整个设计的整体水平的情况下回答是一件棘手的事情。从表面上看,它违反了SRP,但是,使用JavaScript,有时这样做可以使整个代码流更合乎逻辑,更容易理解。在有意义的时候,我倾向于用教条主义来换取实用主义。

我想尝试重构代码,以便它不需要在绘制中调用doSomethingComplex,看看是否更有意义。一般来说,单个函数执行的任务越少,测试和维护代码就越容易,不要忘记错误的可能性越小。

要减少传递所需的变量数,您始终可以将它们包装在一个对象中:

var state = {
 foo: ...,
 bar: ...
 ...
};

doSomethingComplex(state);

通过这样传递状态,你也可以避免关闭相关的副作用。不是说关闭总是很糟糕,但如果你能设法减少一件事,为什么不这样做呢?

同样,所有这些都取决于事物如何适应更大的图片,并使用这些点作为指导。没有银弹。