Я создаю приложение Cordova для Android. Мне нужно разобрать JSON, состоящий из сообщений. Каждый пост имеет текст (название, описание, категорию и т. Д.) И изображения (массив изображений - может быть один или несколько). Моя цель - хранить данные JSON для автономного использования (сохранить в базу данных SQLlite). Сейчас пример код ниже работает, но последовательность не так, как я ожидал:ImgCache - Как правильно подождать, пока асинхронное завершение внутри вложенных циклов
- запрос JSON (ки)
- Дождитесь все обещания (OK)
- Анализировать JSON (заканчивается перед всеми изображения загружаются)
- Храните в базе данных информацию, но изображения, которые все еще загружаются (в фоновом режиме - без вреда для пользовательского интерфейса).
Что бы я хотел иметь, это хранить в базе данных, когда все изображения были загружены. Я пробовал много вещей, таких как замена второго цикла for на рекурсивную функцию (для обработки асинхронной функции, как указано here) и многие другие подобные подходы, но я считаю, что проблема начинается с цикла 1-го цикла, который не ждет для checkCache
, чтобы закончить. Как вы думаете? Как я могу решить эту проблему? Если вам нужны какие-либо дополнительные объяснения, просто спросите меня.
Моя установка: Cordova 4.0.0
, Angular 1.3.1
и ImgCache 1.0
Мой подход:
первым. Запрос JSON:
promise1 = $http({method: 'GET', url: baseURL + options1};
promise2 = $http({method: 'GET', url: baseURL + options2};
//...
2-й. Ждите всех обещаний
return $q.all([promise1,promise2,...]).then(function(data){
var promise1size = data[0].data.posts_number;//posts.length;
parseJSON(data[0],promise1size,'category1');
var promise2size = data[1].data.posts_number;//posts.length;
parseJSON(data[1],promise1size,'category2');
//similar for the rest promises
});
3-й. Анализировать JSON функция
function parseJSON(respdata,size,category){
console.log("Parsing "+size+" "+category);
for(i=0;i<size;i++){
var item = {};
item ["id"] = respdata.data.object[i].id;
item ["title"] = respdata.data.object[i].title;
item ["description"] = respdata.data.object[i].description;
var jsarray = respdata.data.object[i].categories;
item ["category"] = jsarray[0].title;
item ["catid"] = jsarray[0].id;
//Other JSON keys here similar as above
//Here it starts...
var jsattachement = respdata.data.object[i].attachments;
var atsize = jsattachement.length;
if(atsize>0){
var images=[];
for(j=0;j<atsize;j++){
(function(j){checkCache(jsattachement[j].url)}(j));//here is the problem
multimedia.push({title:item["title"], src:ImgCache.returnCachedURL(jsattachement[j].url), w:400,h:300});
images.push({title:item["title"],src:ImgCache.returnCachedURL(jsattachement[j].url),w:400,h:300});
}
item ["attachement"] = images;
}else
item ["attachement"] = [];
if(category=='category1')
response.category1.push(item);
else if(category=='category2')
response.category2.push(item);
//else if...
//else if...
}
}
};
checkCache:
function checkCache (imgsrc){
ImgCache.isCached(imgsrc, function(src, success) {
if(!success){
ImgCache.cacheFile(src, function(){});
}
});
};
четвёртую. Хранить в базе данных
Здесь я сохраняю проанализированную информацию в базе данных. На шаге 3 я использую функцию returnCachedURL
для изображений (которая не является асинхронной), поэтому для того, чтобы локальный путь изображения был готов, даже если он, возможно, еще не был загружен (но в конечном итоге будет).