2012-01-22 6 views
0

Я прочитал верхний ответ this question относительно использования jQuery Deferred.jQuery отложенный кеш ajax

Я перебираю массив идентификаторов. Для каждого идентификатора мне нужно получить данные, относящиеся к нему либо из запроса ajax, либо из кеша, если запрос ajax уже успешно возвратил данные раньше.

В течение каждого цикла я использую $ .when(), чтобы проверить, возвращает ли getData() что-то из кеша или успешный вызов ajax, прежде чем обрабатывать этот идентификатор. Текущая проблема заключается в том, что обработка идентификатора продолжается так или иначе, не дожидаясь успеха ajax getData().

Некоторый псевдокод:

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

Смежные вопросы