Доступ к нескольким JSON файлам в JavaScript
У меня есть листы спрайтов с атласом, сохраненным в формате JSON. Я структурирую свой atlus на основе структуры из BrowserQuest. Каждый из их файлов JSON выглядит так:
{
"id": "agent",
"width": 24,
"height": 24,
"animations": {
"idle_down": {
"length": 2,
"row": 0
}
},
"offset_x": -4,
"offset_y": -8
}
Но мне интересно, как я даже могу получить доступ к данным в каждом файле JSON, если это просто литерал необработанного объекта?
Поскольку каждый JSON файл является объектным литералом, единственный способ, которым я мог бы получить доступ к нему, - это сохранить литерал объекта переменной, например
var agent = {
"id": "agent",
"width": 24,
"height": 24,
"animations": {
"idle_down": {
"length": 2,
"row": 0
}
},
"offset_x": -4,
"offset_y": -8
};
Я надеюсь, что есть простой способ доступа к файлам JSON.
И поскольку каждый отдельный лист спрайтов имеет свой собственный JSON файл, у меня есть большое количество загружаемых файлов.
Каков наилучший способ загрузки такого большого количества файлов JSON? Я пытаюсь избежать использования каких-либо JS-библиотек.
Ответы
Ответ 1
Во-первых, чтобы ответить на ваши вопросы:
Но мне интересно, как я даже могу получить доступ к данным в каждом файле JSON, если это просто литерал необработанного объекта?
JSON обозначает J ava S cript O bject N, и, как таковой, идентичен тому, как это было бы обработано, если бы это был объект JavaScript.
Что касается доступа к файлу JSON, если он был локальным файлом, вы можете использовать это:
function doStuff(json){
console.log(json);
}
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", function(){
doStuff(JSON.parse(this.responseText));
});
oReq.open("GET", "http://www.example.com/example.json");
oReq.send();
И тогда вы можете просто заменить doStuff
любой функцией, обрабатывающей JSON.
Ответ 2
Вы можете использовать XMLHttpObject.
Посмотрите
function getJSONFile(url,callback) {
var req = new XMLHttpRequest();
req.open('GET', url, true);
req.overrideMimeType("application/json");
req.onreadystatechange = function () {
if (req.readyState == 4 && req.status == "200") {
callback(req.responseText);
}
};
req.send();
}
используйте эту функцию следующим образом
getJSONFile('http://www.example.com/example.json', function(data){
if(data)
console.log('json data : ' + JSON.stringify(data));
})
Ответ 3
Вы можете добиться этого с помощью комбинации Promise
и XMLHttpRequest
для загрузки нескольких файлов JSON параллельно.
Эта интересная статья из статьи HTML5Rocks также поможет вам в управлении загрузкой и оптимизации, поскольку она является всеобъемлющей и функциональной.
Например, с помощью функции get(url)
(из приведенной выше статьи см. источник ниже), возвращающий объект JSON как Promise
:
var names = [ "agent", "arrow", ... ]
var sprites = {}
var all = []
names.forEach( function ( n ) {
//Request each individual sprite and get a Promise
var p = get( n + ".json" )
.then( JSON.parse ) //parse the JSON file
.then ( function ( sprite ) {
//Record the sprite by name
sprites[n] = sprite
//Display your sprite as soon as loaded here
} )
//add the promise to an Array of all promises
all.push( p )
} )
//wait for all the files to be loaded and parsed
Promise.all( all )
.then( function () {
//All the JS sprites are loaded here
//You can continue your processing
} )
Источник для get (url):
Вот пример кода из HTML5Rocks. Он инкапсулирует асинхронный вызов XMLHttpRequest в Promise
:
function get(url) {
return new Promise(function(resolve, reject) {
var req = new XMLHttpRequest()
req.open( 'GET', url )
req.onload = function() {
if ( req.status == 200 )
// Resolve the promise with the response text
resolve(req.response)
else
// Otherwise reject with the status text
reject( Error( req.statusText ) )
}
// Handle network errors
req.onerror = function() {
reject( Error( "Network Error" ) )
}
// Make the request
req.send()
} )
}