Вызов нескольких данных/файлов JSON в одном запросе getJson
У меня есть этот код:
var graphicDataUrl = 'templating/graphic-data.json';
var webDataUrl = 'templating/web-data.json';
var templateHtml = 'templating/templating.html';
var viewG = $('#view-graphic');
var viewW = $('#view-web');
$.getJSON(dataUrls, function(data) {
$.get(templateHtml, function(template) {
template = Handlebars.compile(template);
var example = template({ works: data });
viewG.html(example);
viewW.html(example);
});
});
Каков наилучший способ вызова обоих JSON dataUrl и использования их данных, чтобы отображать их в двух разных div (#viewW и #viewW) на моей странице?
Ответы
Ответ 1
Лучший способ - сделать каждый отдельно и обработать условия ошибки:
$.getJSON(graphicDataUrl)
.then(function(data) {
// ...worked, put it in #view-graphic
})
.fail(function() {
// ...didn't work, handle it
});
$.getJSON(webDataUrl, function(data) {
.then(function(data) {
// ...worked, put it in #view-web
})
.fail(function() {
// ...didn't work, handle it
});
Это позволяет повторять запросы параллельно и обновляет страницу как можно скорее, когда каждый запрос завершается.
Если вы хотите запускать запросы параллельно, но подождите, чтобы обновить страницу, пока они не завершатся, вы можете сделать это с помощью $.when
var graphicData, webData;
$.when(
$.getJSON(graphicDataUrl, function(data) {
graphicData = data;
}),
$.getJSON(webDataUrl, function(data) {
webData = data;
})
).then(function() {
if (graphicData) {
// Worked, put graphicData in #view-graphic
}
else {
// Request for graphic data didn't work, handle it
}
if (webData) {
// Worked, put webData in #view-web
}
else {
// Request for web data didn't work, handle it
}
});
... но страница может показаться менее отзывчивой, так как вы не обновляетесь, когда возвращается первый запрос, но только тогда, когда оба делают.
Ответ 2
На всякий случай это полезно для всех, кто может столкнуться с этим — и благодаря обещаниям Promise в jQuery — T.J. Теперь ответ Кроудера можно улучшить в одной краткой и общей функции:
/**
* Load multiple JSON files.
*
* Example usage:
*
* jQuery.getMultipleJSON('file1.json', 'file2.json')
* .fail(function(jqxhr, textStatus, error){})
* .done(function(file1, file2){})
* ;
*/
jQuery.getMultipleJSON = function(){
return jQuery.when.apply(jQuery, jQuery.map(arguments, function(jsonfile){
return jQuery.getJSON(jsonfile);
})).then(function(){
var def = jQuery.Deferred();
return def.resolve.apply(def, jQuery.map(arguments, function(response){
return response[0];
}));
});
};
Однако вопрос о том, чтобы не давать никакой обратной связи пользователю — пока ожидаете полную нагрузку — является хорошим. Поэтому для тех, кто предпочитает давать отзывчивую обратную связь, здесь немного более сложная версия, которая поддерживает прогресс.
/**
* Load multiple json files, with progress.
*
* Example usage:
*
* jQuery.getMultipleJSON('file1.json', 'file2.json')
* .progress(function(percent, count, total){})
* .fail(function(jqxhr, textStatus, error){})
* .done(function(file1, file2){})
* ;
*/
jQuery.getMultipleJSON = function(){
var
num = 0,
def = jQuery.Deferred(),
map = jQuery.map(arguments, function(jsonfile){
return jQuery.getJSON(jsonfile).then(function(){
def.notify(1/map.length * ++num, num, map.length);
return arguments;
});
})
;
jQuery.when.apply(jQuery, map)
.fail(function(){ def.rejectWith(def, arguments); })
.done(function(){
def.resolveWith(def, jQuery.map(arguments, function(response){
return response[0];
}));
})
;
return def;
};