2009-06-01 10 views
39

Ich implementiere einen Rückruf für eine 3rdParty Javascript Bibliothek und ich muss den Wert zurückgeben, aber ich muss den Wert vom Server abrufen. Ich brauche so etwas wie dies zu tun:

3rdPartyObject.getCustomValue = function { 
    return $.getJSON('myUrl'); 
} 

getJSON verwendet XMLHttpRequest, die (glaube ich) hat sowohl synchrone als auch asynchrone Verhalten, kann ich das synchronouse Verhalten verwenden?

+3

Und warum können Sie einen Rückruf nicht für die Rückgabe/den Wert verwenden? Versuchen Sie außerdem, das synchrone Verhalten so weit wie möglich zu vermeiden, da dies die Benutzeroberfläche des Browsers während seiner Verarbeitung blockiert. – PatrikAkerstrand

+0

Der aufrufende Code unterstützt keine Rückrufe. – tpower

Antwort

103

an der Quelle jQuery Suche Code, das ist alles $.getJSON tut:

getJSON: function(url, data, callback) { 
    return jQuery.get(url, data, callback, "json"); 
}, 

Und das ist alles $.get tut:

get: function(url, data, callback, type) { 
    // shift arguments if data argument was omitted 
    if (jQuery.isFunction(data)) { 
     callback = data; 
     data = null; 
    } 

    return jQuery.ajax({ 
     type: "GET", 
     url: url, 
     data: data, 
     success: callback, 
     dataType: type 
    }); 
}, 

Keine schwarze Magie gibt. Da Sie Sachen anders als die grundlegenden $.getJSON Funktionalität anpassen müssen, können Sie einfach die Low-Level-$.ajax Funktion verwenden und die async option als falsch übergeben:

$.ajax({ 
    type: 'GET', 
    url: 'whatever', 
    dataType: 'json', 
    success: function() { }, 
    data: {}, 
    async: false 
}); 
+8

Große Antwort :-) –

+0

Wenn Sie 'async: false' übergeben dann wie erhalten Sie die Fehlermeldung von' $ .ajax'? –

+1

Diese Komfortmethoden sind fast wie Voreinstellungen für die $ .ajax-Funktion. Sie sind nur nützlich, wenn Sie genau diese Ajax-Optionen verwenden. – styfle

3

Aber wenn ich diesen Code täusche nicht funktionieren würde:

3rdPartyObject.getCustomValue = function { 
    var json = $.ajax({ 
    type: 'GET', 
    url: 'whatever', 
    dataType: 'json', 
    success: function() { }, 
    data: {}, 
    async: false 
    }); 

return json; 
} 

Wie $ .ajax gibt das XHR-Objekt nicht das geparste JSON-Objekt zurück.

Sie müssten etwas mehr tun, wie:

var jsonLoader = function(url){ 
    this.url = url; 
    this.rawData = {}; 
    this.getRawData(); 
}; 

jsonLoader.prototype.getRawData = function(){ 

    var json = $.ajax({ 
     type: 'GET', 
     url: this.url, 
     dataType: 'json', 
     success: this.getRawData(this), 
     data: {}, 
     async: false 
    }); 
}; 

jsonLoader.prototype. getRawData = function(self){ 
    return function(json){self.rawData = json;}; 
}; 

var loadMe = new jsonLoader("Data.json"); 
loadMe.rawData //has the parsed json object 

In der Tat hat es wahrscheinlich eine viel sauberere Weg, um das gleiche zu erreichen

7
var jsonObjectInstance = $.parseJSON(
    $.ajax(
     { 
      url: "json_data_plz.cgi", 
      async: false, 
      dataType: 'json' 
     } 
    ).responseText 
); 
15

Sie auch die folgenden, bevor Sie Ihren Anruf verwenden können :

Ich weiß nicht den Umfang der "Async" -Eigenschaft, ich vermute, dass es ein ist Globale Konfiguration Überlegen Sie also, ob Sie dies nach Ihrem synchronen Aufruf wieder auf true setzen möchten.

Beispiel:

3rdPartyObject.getCustomValue = function { 
    $.ajaxSetup({ "async": false }); 
    var result = $.getJSON('myUrl'); 
    $.ajaxSetup({ "async": true }); 
    return result; 
} 
+1

Das funktioniert! –

0

Der Umfang der Asynchron-Eigenschaft global ist, wird Ihre Methode um den Anruf synchronisieren.

2

Wenn jemand jemals in Schienen zu tun hat, habe ich eine ziemlich saubere Art und Weise wie folgt aus:

Richten Sie Ihre Controller wie folgt aus:

def my_ajax_action 

    respond_to do |format| 
     # if you use render, you won't need a view page, the ":json =>" part takes care of all 
     # the formatting 
     format.json { render :json => @variable_containing_json } 
    end 

end 

Einrichtung der Anruf in Javascript

function doAjaxWork() { 

    var ret; 

    $.ajax({ 
     type: 'GET', 
     url: '/controller/action/param', 
     dataType: 'json', 
     complete: function(response) { 
      ret = eval('(' + response.responseText + ')'); 
     }, 
     async: false 
    }); 


    return ret; 
} 

Natürlich tun Sie nicht diese Synchronisierung Sachen, wenn Sie müssen. Oh, und während ich Javascript mit URLs darin zeige, schau dir JSRoutes an ...es macht diese wirklich sauber.

Verwandte Themen