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);
}

HTMLのどこかで呼び出すとreadSettings()、最初のアラート(callAjax関数でJSONを正しくアラートしますが、2番目のアラートはそうではありません。コンソールを見ると、エラーは次のとおりです。

[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

関数から値を返していませんcallAjaxonreadystatchange結果を使用するコードをハンドラー内に配置する必要があります。

ステートメントはありますが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後すぐにできることです。コールバックが実行されるcallAjax前。onreadystate操作の非同期性のため、コールバックから解析をトリガーする必要があります。

于 2013-10-27T15:37:54.990 に答える
1

AJAX の「A」は非同期を表します。XMLHttpRequest を送信した後、callAjax関数はリクエストの完了を待たずにすぐに戻ります。したがって、(探している JSON ではない)JSON.parseの戻り値で が呼び出され、エラーが生成されます。callAjax

しばらくして、XMLHttpRequest が完了し、onreadystatechangeコールバックが実行されます。この関数から JSON を返しますが、JSON は からではなくコールバックから返されるため、どこにも行きませんcallAjax

onreadystatechangeイベントの結果として、JSON 解析と後続のアクティビティを実行する必要があります。

于 2013-10-27T15:42:17.640 に答える