Est-il possible de définir async: false sur l'appel $ .getJSON

105

Est-il possible de définir async: falselors de l'appel de $.getJSON()sorte que l'appel bloque plutôt que d'être asynchrone?

ACP
la source
1
Il suffit de mettre votre code dans le callback .... Il y a une raison pour laquelle c'est obsolète - c'est une mauvaise idée
Milney
1
@Milney - Très étrange… Officiellement, il est obsolète; en fait, ce n'est pas le cas . S'il était vraiment obsolète, la possibilité d'effectuer un appel de synchronisation AJAX ou un commutateur $ ajax.setup aurait été abandonnée dans jQuery 3. En fait, un appel de synchronisation est parfois très utile, par exemple lors de l'initialisation des globaux avec Données JSON, lorsque vous avez d'autres globaux qui reposent sur le premier lot. (Emballer tout le processus d'initialisation dans la fonction de rappel peut être très délicat dans certaines circonstances.)
Brice Coustillas
Je pense que les requêtes XHR synchrones ou le code de restructuration répondraient à ce cas.
Chetabahana

Réponses:

154

Vous devez effectuer l'appel en l'utilisant $.ajax()de manière synchrone, comme ceci:

$.ajax({
  url: myUrl,
  dataType: 'json',
  async: false,
  data: myData,
  success: function(data) {
    //stuff
    //...
  }
});

Cela correspondrait à l'utilisation actuelle $.getJSON()comme ceci:

$.getJSON(myUrl, myData, function(data) { 
  //stuff
  //...
});
Nick Craver
la source
23
J'ai trouvé la méthode pratique $ .getJSON () presque jamais utile, et finit toujours par utiliser $ .ajax ().
Jacob Marble
puis-je également l'utiliser pour un appel POST?
Hitesh
@hitesh oui, vous ajouteriez également une type: 'POST'option pour en faire un article - bien que vous ne souhaitiez pas l'utiliser à async: falsemoins que vous n'en ayez vraiment besoin - cela bloquera l'interface utilisateur.
Nick Craver
1
Que doit être "myData" dans ce cas? Quand je supprime des données: myData complètement ça marche .. Assez nouveau pour les appels ajax!
nclsvh
2
Je viens de tomber sur le nouveau problème suivant: "XMLHttpRequest synchrone en dehors des nœuds de calcul est en cours de suppression de la plate-forme Web car il a des effets néfastes sur l'expérience de l'utilisateur final. (Il s'agit d'un processus long qui prend de nombreuses années.) Les développeurs doivent ne pas transmettre false pour l'argument async lorsque l'objet global de l'objet de paramètres d'entrée est un objet Window. Les agents utilisateurs sont vivement encouragés à avertir d'une telle utilisation dans les outils de développement et peuvent expérimenter en levant une exception InvalidAccessError lorsqu'elle se produit. "
Ken Sharp
46

Les deux réponses sont fausses. Vous pouvez. Vous devez appeler

$.ajaxSetup({
async: false
});

avant votre appel json ajax. Et vous pouvez le définir sur true après la relance de l'appel (s'il y a d'autres utilisations d'ajax sur la page si vous les voulez asynchrones)

Velja
la source
1
Je viens de relire cette partie de la documentation. Voici la partie qui parle d'ajaxSetup: api.jquery.com/jQuery.ajaxSetup Et voici les options: api.jquery.com/jQuery.ajax Il dit clairement: "async Par défaut: true Par défaut, toutes les demandes sont envoyées de manière asynchrone ( c'est-à-dire défini sur true par défaut). Si vous avez besoin de requêtes synchrones, définissez cette option sur false. Requêtes interdomaines et dataType: les requêtes "jsonp" ne prennent pas en charge le fonctionnement synchrone. "JSONP n'est pas JSON donc je pense toujours que je suis dès le début. J'écrirai un exemple plus tard quand j'aurai du temps.
velja du
7
Ceci est un commentaire tardif mais ... quelles sont les réponses «à la fois» qui sont fausses? Je vois que la réponse de @Nick Craver est à la fois acceptable et non "gâchée" avec les paramètres AJAX globaux (si d'autres demandes se déclenchent en même temps)
scunliffe
1
Cela fonctionne, mais cela s'appliquerait à toutes les demandes ajax que vous faites dans la page. Donc je vais contrevoter car je ne le recommanderais pas
GabrielBB
3
C'est une réponse de très mauvaise qualité
Brian Webster
1
-1: Rendre les choses synchrones peut être coûteux. Vous devriez certainement le faire sur une base par appel, sauf si votre projet l'exige absolument à chaque fois. Votre réponse suggère que vous configurez globalement tous les appels vers $.ajax(et emballages sténographiques ultérieurs à savoir $.getJSON, $.getetc.) pour être synchrone. De plus, la documentation suggère même de ne pas utiliser ceci: "Description: Définissez les valeurs par défaut pour les futures requêtes Ajax. Son utilisation n'est pas recommandée."
Carrie Kendall
18

Je pense que vous avez tous les deux raison. La dernière réponse fonctionne bien, mais c'est comme définir une option globale, vous devez donc faire ce qui suit:

    $.ajaxSetup({
        async: false
    });

    //ajax call here

    $.ajaxSetup({
        async: true
    });
webdev
la source
10

Dans mon cas, Jay D a raison. Je dois ajouter ceci avant l'appel.

$.ajaxSetup({
    async: false
});

Dans mon code précédent, j'ai ceci:

var jsonData= (function() {
    var result;
    $.ajax({
        type:'GET',
        url:'data.txt',
        dataType:'json',
        async:false,
        success:function(data){
            result = data;
        }
    });
    return result;
})();
alert(JSON.stringify(jsonData));

Cela fonctionne trouver. Puis je change pour

var jsonData= (function() {
    var result;
    $.getJSON('data.txt', {}, function(data){
      result = data;
    });
    return result;
})();
alert(JSON.stringify(jsonData));

L'alerte n'est pas définie.

Si j'ajoute ces trois lignes, l'alerte affiche à nouveau les données.

$.ajaxSetup({
    async: false
});
var jsonData= (function() {
    var result;
    $.getJSON('data.txt', {}, function(data){
      result = data;
    });
    return result;
})();
alert(JSON.stringify(jsonData));
ronrun
la source
1

Si vous avez juste besoin awaitd'éviter l'imbrication du code:

let json;
await new Promise(done => $.getJSON('https://***', async function (data) {
    json = data;
    done();
}));
k06a
la source
0

Je ne pense pas que vous puissiez définir cette option ici. Vous devrez utiliser jQuery.ajax () avec les paramètres appropriés (en gros, getJSON encapsule simplement cet appel dans une API plus simple).

Daff
la source
0

Roulez votre propre par exemple

function syncJSON(i_url, callback) {
  $.ajax({
    type: "POST",
    async: false,
    url: i_url,
    contentType: "application/json",
    dataType: "json",
    success: function (msg) { callback(msg) },
    error: function (msg) { alert('error : ' + msg.d); }
  });
}

syncJSON("/pathToYourResouce", function (msg) {
   console.log(msg);
})
Stonedecroze
la source