2013-10-27 8 views
0

Вот мой файла JavaScriptНе удается разобрать JSON?

var callAjax = function(relative_path){ 
     var Ajax = new XMLHttpRequest(); 
      Ajax.onreadystatechange = function() { 

       //Since what we are calling a local file. we cannot get a 200 OK Status. 
       //So We check only the readystate 
       if(Ajax.readyState==4){ 
        serialized = Ajax.responseText; 
        alert(serialized); 
        // ^^ alerts fine. 
        return serialized; 
       } 

      } 

      Ajax.open("GET",relative_path, true); 
      Ajax.send();  
}; 


var readSettings = function(){ 
    var data = callAjax('settings.json'); 
    obj = JSON.parse(data); 
    alert(obj); 
} 

Теперь, когда я называю readSettings() где-то в моем HTML, первое предупреждение (в функциях callAjax оповещает JSON правильно. Но второй один не делает. Когда я вижу консоль, ошибка:

[21:04:02.233] SyntaxError: JSON.parse: unexpected character @ file:///home/cipher/Codes/looma-f5/js/looma.js:23

Мой settings.json является:

{ 

    "classes": 8, 
    "config": "classConfig", 
    "locale": { 
     "en": "localeEn" 
    }, 
    "defaultLocale": "en" 
} 

Я побежал JSON через онлайн-инструментов, это выглядит г ООД. Почему firefox не разбирает их?

+0

Ваш json в utf-8? – Sumurai8

+0

Я вижу, что это была не настоящая причина ошибки :). В любом случае, спасибо @ Sumurai8 – cipher

ответ

3

Вы не возвращаете значения из функции callAjax. Вам нужно поместить свой код, который использует результат внутри обработчика onreadystatchange.

Вы сделать есть return заявления, но внутри обратного вызова, который возвращает к внутреннему абоненту обратного вызова, и которая вызывается после того, как ваш callAjax вернулся.

Поскольку кажется, что callAjax довольно общий, хороший подход состоит в том, чтобы эта функция принимала обратный вызов в качестве аргумента, а затем вызывала его, передавая ответ.

//     receive a callback----vv 
var callAjax = function(relative_path, callback){ 
     var Ajax = new XMLHttpRequest(); 

     Ajax.onreadystatechange = function() { 
      if(Ajax.readyState==4){ 
       serialized = Ajax.responseText; 
       alert(serialized); 

       // vv---invoke the callback 
       callback(serialized); 
      } 
     } 
     Ajax.open("GET",relative_path, true); 
     Ajax.send(); 
}; 

var readSettings = function(){ 
    // pass a callback ----------------------vv 
    var data = callAjax('settings.json', function(data) { 
     var obj = JSON.parse(data); 
     alert(obj); 
    }); 
} 

Если вызывающий readSettings потребности работать с ответом, то вы могли бы readSettings также получить обратный вызов, а затем либо передать его непосредственно, или обернуть его в другую функцию так, что она может сначала выполните синтаксический анализ.

Я приведу пример, предполагающий, что его нужно обернуть.

// receive a callback----------vv 
var readSettings = function(callback){ 
    // pass a callback that wraps the first---vv 
    var data = callAjax('settings.json', function(data) { 
     // parse the response data 
     var obj = JSON.parse(data); 

     // invoke the callback, passing it the parsed object 
     callback(obj); 
    }); 
} 

readSettings(function(settings_obj) { 
    alert(settings_obj); 
}); 
+0

Если положить код в обработчик обратного вызова - это хороший старт, я бы не рекомендовал в нем размещать весь будущий код;) (просто боковое примечание). –

+0

Молодцы;) +1 –

+0

@ MichaelKrelin-hacker: Спасибо :) –

2

Проблема в том, что вы можете JSON.parse сразу после callAjax возвращается. Перед выполнением обратного вызова onreadystate. Из-за асинхронного характера операции вы должны инициировать анализ из обратного вызова.

1

"А" в AJAX для асинхронного. После отправки XMLHttpRequest функция callAjax вернется немедленно, не дожидаясь завершения запроса. Таким образом, вызывается JSON.parse с возвращаемым значением callAjax (который не является JSON, который вы ищете), генерируя ошибку.

Спустя некоторое время будет завершен запрос XMLHttpRequest и будет выполнен обратный вызов . Вы возвращаете JSON из этой функции, но JSON никуда не денется, потому что он возвращается из обратного вызова, а не из callAjax.

Вы должны выполнить разбор JSON и последующие действия в результате события onreadystatechange.

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