0

这是我的 javascript 文件

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: 意外字符@file:///home/cipher/Codes/looma-f5/js/looma.js:23

我的 settings.json 是:

{

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

我通过在线工具运行了 JSON,它看起来不错。为什么Firefox不解析这些?

4

3 回答 3

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);
});
于 2013-10-27T15:38:35.443 回答
2

问题是您可以在返回JSON.parse后立即。callAjaxonreadystate执行回调之前。由于操作的异步性质,您应该从回调触发解析。

于 2013-10-27T15:37:54.990 回答
1

AJAX 中的“A”表示异步。提交 XMLHttpRequest 后,该callAjax函数将立即返回,无需等待请求完成。因此,将使用(不是您要查找的 JSON)JSON.parse的返回值调用 ,从而生成错误。callAjax

一段时间后,XMLHttpRequest 将完成并onreadystatechange运行回调。您从此函数返回 JSON,但 JSON 不会去任何地方,因为它是从回调返回的,而不是从callAjax.

作为事件的结果,您必须执行 JSON 解析和后续活动onreadystatechange

于 2013-10-27T15:42:17.640 回答