2009-06-01 2 views
39

Je suis en train d'implémenter un callback pour une librairie javascript 3rdParty et j'ai besoin de retourner la valeur, mais j'ai besoin de récupérer la valeur du serveur. Je dois faire quelque chose comme ceci:

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

getJSON utilise XMLHttpRequest qui (je crois) a deux comportements synchrones et asynchrones, puis-je utiliser le comportement de synchronouse?

+3

Et pourquoi ne pouvez-vous pas utiliser un rappel pour retourner/obtenir la valeur? En outre, essayez d'éviter autant que possible le comportement synchrone, car il verrouillera l'interface utilisateur du navigateur pendant son traitement. – PatrikAkerstrand

+0

Le code appelant ne prend pas en charge les rappels. – tpower

Répondre

103

En regardant le code source jQuery, cela est $.getJSON fait:

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

Et cela est $.get fait:

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

Pas de magie noire là-bas. Puisque vous avez besoin de personnaliser des choses autres que la fonctionnalité $.getJSON de base, vous pouvez simplement utiliser la fonction de bas niveau $.ajax et passer le async option comme faux:

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

Grande réponse :-) –

+0

lorsque vous passez 'async: false' alors comment obtenez-vous le message d'erreur de' $ .ajax'? –

+1

Ces méthodes de commodité sont presque comme des préréglages pour la fonction $ .ajax. Ils ne sont utiles que si vous utilisez ces options ajax exactes. – styfle

3

Mais à moins que je me trompe ce code ne fonctionnerait pas:

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

return json; 
} 

Lorsque $ .ajax renvoie l'objet XHR et non l'objet json analysé.

Vous devez faire quelque chose comme:

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 

En fait, il est probablement une manière beaucoup plus propre d'atteindre le même

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

Vous pouvez également utiliser les points suivants avant de faire votre appel :

$.ajaxSetup({ "async": false }); 

Je ne connais pas la portée de la propriété "async", je suppose que c'est un config globale Considérez donc si vous voulez revenir à la réalité après votre appel synchrone.

exemple:

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

Cela ne fonctionne pas! –

0

La portée de la propriété async est globale, votre méthode synchroniser l'appel.

2

Si quelqu'un a jamais le faire dans des rails, j'ai une façon assez propre comme ceci:

Configurez votre contrôleur comme ceci:

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 

Configuration de l'appel en 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; 
} 

Bien sûr, ne faites pas ce truc de synchronisation, sauf si vous devez le faire. Oh et pendant que je montre javascript avec des urls dedans, consultez JSRoutes ...ça les rend vraiment propres.

Questions connexes