【问题标题】:Cache each JSON search query with localStorage使用 localStorage 缓存每个 JSON 搜索查询
【发布时间】:2014-09-03 16:40:33
【问题描述】:

提示:我们有一个连接到 JSON API url 的搜索。搜索查询在 url 内,API 为每个搜索词生成一个新的 JSON 文件。我们也不能依赖浏览器为我们缓存,也不能使用PHP或者服务器端缓存;我们需要使用 HTML5 LocalStorage(而且我们不在乎 IE7 不能使用它)

我们需要为每个新搜索缓存每个新的 JSON 文件。我们希望减少每分钟的请求数,因此我们希望使用 JSON 文件的缓存版本来重复搜索词。

我卡在哪里了:让这变得困难的是为每个新的/不同的搜索词缓存一个 JSON 文件。我已经能够缓存第一个搜索,但是所有后续搜索都使用相同的缓存 JSON。

我们需要帮助重写它,因此每次进行新搜索时,它都会检查该词是否以前搜索过,如果是,则获取相应的 JSON 文件。当然,如果搜索词是新的,则为该特定搜索词缓存一个新的 JSON 文件。

我的尝试:在我的研究中,我看到了很多非常复杂的解决方案,但我似乎无法完全理解所有这些解决方案,其中一些解决方案几乎工作,我想我只需要对这个具体案例进行更好的解释。

我认为这是答案,但我不知道如何将其应用于我的情况:jQuery deferred ajax cache

这太疯狂了,它几乎可以工作,当它识别出我再次搜索了相同的东西时它会写入控制台,并且它确实停止了一个新请求,但不幸的是缓存的 JSON 不存在,它返回 no结果。 Caching a jquery ajax response in javascript/browser

到目前为止我有什么:

我的伪代码:

var searchTerm = WHATEVER IS TYPED INTO THE SEARCHBOX

// The JSON file
var url = 'https://api.example.com/fake/json/path/{'+searchTerm+'}';

// Local Storage Caching Promise
var cachedData = localStorage.getItem("cachedData"),
          def = $.Deferred();

if (!cachedData) {
    def = $.getJSON(url, function(data) {
        cachedData = data;
        localStorage.setItem("cachedData", JSON.stringify(cachedData));
    });
}
else{
    cachedData = JSON.parse(cachedData);
    def.resolve();
}

def.done(function() {
    var resultHTML = '';
    for(var i = 0; i < Object.keys(cachedData.things).length; i++){
      $.each(cachedData, function(index, node){
        resultHTML += '<li>'
        resultHTML  += '<h1>' + node[i].name + '</h1>';
        resultHTML += '</li>';
      });
    }
    $('div#results').html(resultHTML);

});

示例 JSON:

{
  "things": [
    {
      "type": "thing",
      "username": "randoguy",
      "name": "name001",
    },
       {
      "type": "thing2",
      "username": "randoguy2",
      "name": "name002",
    },
    ...

【问题讨论】:

  • 你有一堆异步代码,但你把它当作同步的。首先,不要使用def.resolve(),而是使用def.resolve(cachedData)。然后,代替def.done(function() {,使用def.done(function(data) {,并在回调中使用data。这样,done 回调将在正确的时间使用正确的数据被调用(无论是来自localStorage 还是$.getJSON 调用)
  • 另外,您将无法简单地存储cachedData,因为您需要为任何searchTerm 提供缓存结果。因此,您可以制作许多 localStorage 项目(如 searchTerm + "cachedData"), or make a big object that has a lookup per searchTerm`
  • 哇,感谢@Ian 的快速回复,我想使用searchTerm + "cachedData" 创建许多localStorage 项目,您认为您可以详细说明该代码的去向吗?
  • @LookingLA 所以,任何时候你调用localStorage.getItemlocalStorage.setItem,第一个参数都应该是.getItem(searchTerm + "-cachedData")。这样,每个搜索词在localStorage 中都有一个唯一的结果。保存也是如此 - .setItem(searchTerm + "-cachedData")。我添加了"-cachedData" 只是为了确保搜索词不会干扰您的网站使用localStorage 用于键可能重叠的任何其他内容
  • @Ian 你是我的英雄,现在完美运行!很简单!谢谢!

标签: javascript json search caching local-storage


【解决方案1】:

感谢@Ian 为我的回答提供提示!

var searchTerm = WHATEVER IS TYPED INTO THE SEARCHBOX;

// The JSON file
var url = 'https://api.example.com/fake/json/path/{'+searchTerm+'}';

// BABAM! Right here, SearchTerm + "-cachedData" gets unique cached data
var cachedData = localStorage.getItem(searchTerm + "-cachedData"),
          def = $.Deferred();

if (!cachedData) {
    def = $.getJSON(url, function(data) {
        cachedData = data;
// BABAM! And here is where the unique cachedData is set! SearchTerm + "-cachedData"
        localStorage.setItem(searchTerm + "-cachedData", JSON.stringify(cachedData));
    });
}
else{
    cachedData = JSON.parse(cachedData);
    def.resolve(cachedData);
}

def.done(function(data) {
    var resultHTML = '';
    for(var i = 0; i < Object.keys(data.repositories).length; i++){
      $.each(data, function(index, node){
        resultHTML += '<li>'
        resultHTML  += '<h1>' + node[i].name + '</h1>';
        resultHTML  += '<p>' + node[i].owner + '</p>';
        resultHTML += '</li>';
      });
    }
    $('div#results').html(resultHTML);

});

如果没有 StackOverflow,我会在哪里。谢谢大家!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多