Доступ к нескольким 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()
  } )
}