2012-01-22 44 views
0

我看了上面的答案this question关于使用jQuery DeferredjQuery的递延AJAX缓存

我通过ID数组循环。对于每一个ID,我需要得到有关它无论是从一个Ajax请求,或从缓存中的数据,如果一个Ajax请求已经成功之前返回的数据。

在每个循环中,我使用了一个$。当()观察的getData()返回是否从高速缓存或一个成功的Ajax调用的东西,加工该ID之前。目前的问题是ID处理无论如何都不会等待getData()的ajax成功。

一些伪代码:

var IDs = ["1", "2", "1", "3", "1"]; 
//ID "1" is repeated 
//data for "1" should should require ajax get the first time 
//subsequent processing should get data for "1" from dataCache 

var dataCache = []; 

function getData(ID){ 
    if (/*data for ID in dataCache*/){ 
     //return data pertaining to ID from dataCache 
    } else { 
     return $.getJSON("returnJSONDataByID/" + ID, function(resp){ 
      //push resp data to dataCache 
     }) 
    } 
} 

for (/*each item i in IDs*/){ 
    $.when(getData(IDs[i])).then(function(){ 
     //process IDs[i] data 

     //this is the resolved handler, which should be executed 
     //when either getData() returns data from the dataCache, 
     //or $.getJSON succeeds 
     //PROBLEM: this is currently executing every loop and 
     //and doesn't wait for the ajax to return resp 
    }) 
} 

回答

5

的问题是,你的循环将立即解雇所有getData的呼叫,但结果仅存储在缓存中一旦JSON调用返回。因此,对于循环中的每个调用,缓存仍为空,并且每个都将执行新的JSON请求。

解决方案:代替将结果存储在高速缓存中的对象Deferred

var IDs = ["1", "2", "1", "3", "1"]; 

var dataCache = {}; 

function getData(id) { 
    if (id in dataCache) { 
     console.log("Cache hit for ID " + id); 
     return dataCache[id]; 
    } else { 
     console.log("Retrieving data for ID " + id); 
     var deferred = $.getJSON("http://jsfiddle.net/echo/jsonp/?callback=?", { 
      id: id 
     }, function(response) { 
      console.log("Retrieved data for ID " + id); 
     }); 
     dataCache[id] = deferred; 
     return deferred; 
    } 
} 

for (var i=0; i<IDs.length; i++) { 
    $.when(getData(IDs[i])).then(function(result) { 
     console.log("result: " + result.id); 
    }); 
} 

注意:这是工作代码,您可以play with it in jsFiddle

+0

这是我面临这样的问题24个小时内和您的解决方案解决了这个问题。 谢谢 – Stormsson