Y a-t-il une raison d'utiliser une XMLHttpRequest synchrone?

il semble que la plupart des gens font des requêtes asynchrones avec XMLHttpRequest mais évidemment le fait qu'il existe la possibilité de faire des requêtes synchrones indique qu'il pourrait y avoir une raison valable pour le faire. Donc, ce que pourrait être cette raison valable?

82
demandé sur Darrell Brogdon 2010-01-18 21:36:31

18 réponses

je pense qu'ils pourraient devenir plus populaires au fur et à mesure que les standards HTML 5 progressent. Si une application web est donné accès à des travailleurs web, Je pourrais prévoir des développeurs utilisant un travailleur web dédié à faire des demandes synchrones pour, comme Jonathan dit, pour s'assurer qu'une demande se produit avant une autre. Avec la situation actuelle d'un thread, c'est un design Moins qu'idéal car il bloque jusqu'à ce que la demande soit complète.

25
répondu D.C. 2018-01-11 12:38:42

Xhrs synchrones sont utiles pour enregistrer les données de l'utilisateur. Si vous gérez l'événement beforeunload , vous pouvez télécharger des données sur le serveur lorsque l'utilisateur ferme la page.

si cela était fait en utilisant l'option async, alors la page pourrait fermer avant que la demande ne soit terminée. Cela permet de s'assurer que la requête est complète ou échoue de la manière attendue.

29
répondu Sami Samhuri 2011-08-04 16:40:08

mise à jour:

ce qui suit laisse entendre - mais sans succès - qu'avec l'avènement d'un meilleur traitement asynchrone des requêtes, il n'y a vraiment aucune raison d'utiliser des requêtes synchrones, à moins d'avoir l'intention d'empêcher délibérément les utilisateurs de faire quoi que ce soit jusqu'à ce qu'une requête soit complète - sons malveillants:)

bien que, cela puisse sembler mauvais, il peut y avoir des moments où il est important qu'une requête (ou une série de requêtes) se produisent avant un utilisateur sort d'une page, ou avant qu'une action soit effectuée - bloquer l'exécution d'un autre code (par exemple, empêcher le bouton de retour) pourrait éventuellement réduire les erreurs/la maintenance pour un mal système conçu; cela dit, Je ne l'ai jamais vu dans le sauvage et le stress qu'il devrait être évité.

Bibliothèques, comme promesse , feindre la synchronicité par le chaînage des processus via des rappels. Cela convient à la majorité des besoins de développement lorsque le désir est d'avoir des événements ordonnés, non-bloquants qui permettent aux navigateurs de conserver la réactivité pour l'utilisateur (bon UX).

Comme , a déclaré à l'Mozilla docs il y a des cas où vous devez utiliser des requêtes synchrones; mais, également répertorié est une solution qui utilise des phare (non disponible dans IE/Safari) pour de tels cas. Bien que cela soit expérimental, si jamais il atteint normes-acceptation, il pourrait peut-être mettre un clou dans le cercueil synchrone.


vous voulez effectuer des appels synchrones dans n'importe quelle sorte de traitement semblable à une transaction, ou partout où un ordre d'opération est nécessaire.

par exemple, disons que vous voulez personnaliser un événement pour vous déconnecter après avoir joué une chanson. Si l'opération de déconnexion se produit en premier, alors la chanson ne sera jamais jouée. Cela nécessite de synchroniser les requêtes.

Une autre raison serait de travailler avec un service web, surtout si vous faites des maths sur le serveur.

exemple: serveur a une variable avec une valeur de 1.

 Step (1) Perform Update: add 1 to variable
 Step (2) Perform Update: set variable to the power of 3
 End Value: variable equals 8

si L'Étape (2) se produit en premier, alors la valeur finale est 2, pas 8; ainsi l'ordre d'opération importe et la synchronisation est nécessaire.


il y a très peu de fois qu'un l'appel synchrone peut être justifié dans un exemple courant du monde réel. Peut-être lorsque vous cliquez sur connexion, puis en cliquant sur une partie du site qui nécessite que l'utilisateur connecté.

comme d'autres l'ont dit, il va attacher votre navigateur, alors restez loin de lui où vous le pouvez.

au lieu des appels synchrones, bien que, souvent les utilisateurs veulent arrêter un événement qui est en train de charger et puis effectuer une autre opération. D'une certaine manière, c'est la synchronisation, puisque le le premier événement est arrêté avant le deuxième commence. Pour ce faire, utilisez la méthode abort() sur l'objet de connexion xml.

12
répondu vol7ron 2016-03-16 05:53:02

je dirais que si vous envisagez de bloquer le navigateur de l'utilisateur pendant que la requête remplit acceptable, puis bien utiliser une requête synchrone.

si la sérialisation des requêtes est votre but, alors ceci peut être accompli en utilisant async requests, en ayant le callback complet de votre requête précédente en ligne.

8
répondu hobodave 2010-01-18 18:40:15

je peux voir une utilisation pour les requêtes XHR synchrones à utiliser quand une ressource dans un emplacement variable doit être chargée avant d'autres ressources statiques dans la page qui dépendent de la première ressource pour fonctionner pleinement. En fait, je suis en train d'implémenter une telle requête XHR dans un petit sous-projet de ma propre initiative alors que les ressources JavaScript résident dans des emplacements variables sur le serveur en fonction d'un ensemble de paramètres spécifiques. Les ressources JavaScript ultérieures dépendent de ces ressources variables et telles les fichiers doivent être garantis de charger avant que les autres fichiers dépendants ne soient chargés, rendant ainsi l'application entière.

Que l'idée de la fondation de vraiment s'étend sur vol7ron de réponse. Les procédures basées sur les transactions sont vraiment le seul moment où des requêtes synchrones doivent être faites. Dans la plupart des autres cas, les appels asynchrones sont la meilleure alternative dans laquelle, après l'appel, le DOM est mis à jour si nécessaire. Dans de nombreux cas, tels que les systèmes basés sur l'utilisateur, vous pourriez avoir certains caractéristiques verrouillé "les utilisateurs non autorisés" jusqu'à ce qu'ils ont, en soi, connecté. Ces fonctionnalités, après l'appel asynchrone, sont déverrouillées via une procédure de mise à jour DOM.

je dois enfin dire que je suis d'accord avec les points de vue de la plupart des individus sur la question: dans la mesure du possible, les requêtes XHR synchrones doivent être évitées car, avec la façon dont cela fonctionne, le navigateur se bloque avec des appels synchrones. Lors de la mise en œuvre des requêtes synchrones, elles doivent être effectuées d'une manière le navigateur devrait normalement être verrouillé, de toute façon, disons dans la section tête avant que le chargement de page ne se produit réellement.

6
répondu hyponiq 2010-07-23 19:07:11

il y a de nombreux cas dans le monde réel où le blocage de L'UI est exactement le comportement désiré.

prend une application avec plusieurs champs et certains champs doivent être validés par un appel xmlhttp vers un serveur distant en fournissant comme entrée la valeur de ce champ et d'autres valeurs de champs.

En mode synchrone, la logique est simple, le blocage expérimentés par l'utilisateur est très court et il n'y a pas de problème.

en mode async, l'utilisateur peut modifiez les valeurs de tous les autres champs pendant que le premier est en cours de validation. Ces modifications déclencheront d'autres appels xmlhttp avec des valeurs du champ initial non encore validées. Que se passe-t-il si la validation initiale échoue ? Pur gâchis. Si le mode sync devient obsolète et interdit, la logique d'application devient un cauchemar à gérer. Fondamentalement, l'application doit être réécrite pour gérer les serrures (par ex. désactiver les autres éléments au cours des processus de validation). La complexité du Code augmente énormément. Ne pas le faire peut conduire à une défaillance de la logique et, en fin de compte, à la corruption des données.

fondamentalement, la question Est: qu'est-ce qui est plus important, L'expérience de L'assurance-chômage non bloquée ou le risque de corruption des données ? La réponse doit rester entre les mains du développeur de l'application, et non du W3C.

5
répondu Alexandre Avrane 2015-04-02 16:33:08

jQuery utilise L'AJAX synchrone en interne dans certaines circonstances. Lorsque vous insérez des scripts HTML qui contiennent des scripts, le navigateur ne les exécute pas. Les scripts doivent être exécutés manuellement. Ces scripts peuvent attacher des gestionnaires de clic. Supposons qu'un utilisateur clique sur un élément avant que le gestionnaire est attaché et la page ne fonctionne pas comme prévu. Par conséquent, pour empêcher les conditions de course, L'AJAX synchrone serait utilisé pour récupérer ces scripts. Parce que l'AJAX synchrone bloque efficacement tout le reste, il peut être sûr que les scripts et les événements exécuter dans le bon ordre.

4
répondu Henry Chan 2011-12-10 16:00:04

depuis 2015, les applications bureautiques javascript sont de plus en plus populaires. Habituellement dans ces applications lors du chargement de fichiers locaux (et le chargement à L'aide de XHR est une option parfaitement valide), la vitesse de chargement est si rapide qu'il y a peu de point pour surcharger le code avec async. Bien sûr, il peut y avoir des cas où async est le chemin à suivre (demande de contenu sur internet, chargement de gros fichiers ou un grand nombre de fichiers dans un seul lot), mais sinon la synchronisation fonctionne très bien (et est beaucoup plus facile utiliser.)

3
répondu jahu 2015-12-25 19:23:46

que se passe-t-il si vous faites un appel synchrone en code de production?

Le ciel tombe vers le bas.

Non sérieusement, l'utilisateur n'aime pas un navigateur verrouillé.

2
répondu martinr 2010-01-18 18:41:33

- je l'utiliser pour valider un nom d'utilisateur, lors de l'enregistrement que le nom d'utilisateur n'existe pas déjà.

je sais qu'il serait préférable de le faire de façon asynchrone, mais je devrais alors utiliser un code différent pour cette règle de validation particulière. J'explique mieux. Ma configuration de validation utilise certaines fonctions de validation, qui renvoient true ou false, selon que les données sont valides.

puisque la fonction doit revenir, Je ne peux pas utiliser de techniques asynchrones, donc je il suffit de faire que synchrone et l'espoir que le serveur répondra assez rapidement pour ne pas être trop perceptible. Si J'utilisais un rappel AJAX, alors je devrais gérer le reste de l'exécution différemment des autres méthodes de validation.

2
répondu Andrea 2010-01-18 18:41:58

parfois vous avez une action qui dépend dans les autres. Par exemple, l'action B ne peut être lancée que si A est terminé. L'approche synchrone est habituellement utilisée pour éviter conditions de course . Parfois, utiliser un appel synchrone est une implémentation plus simple que de créer une logique complexe pour vérifier chaque État de vos appels asynchrones qui dépendent les uns des autres.

Le problème avec cette approche est que vous "bloquer" le navigateur de l'utilisateur jusqu'à ce que le l'action est terminée (jusqu'à ce que la requête revienne, finisse, charge, etc.). Soyez donc prudent lorsque vous l'utilisez.

2
répondu GmonC 2010-01-18 18:49:42

j'utilise des appels synchrones lors de l'élaboration du code - quoi que vous ayez fait pendant que la requête se dirigeait vers et depuis le serveur peut obscurcir la cause d'une erreur.

quand ça marche, je le rends asynchrone, mais j'essaie d'inclure un temporisateur d'Annulation et des rappels d'échec, parce qu'on ne sait jamais...

2
répondu kennebec 2010-01-18 22:38:47

raison:

disons que vous avez une application ajax qui a besoin de faire une demi-douzaine http obtient de charger diverses données du serveur avant que l'utilisateur peut faire n'importe quelle interaction.

évidemment, vous voulez que cela soit déclenché par onload.

les appels synchrones fonctionnent très bien pour cela sans aucune complexité supplémentaire au code. Il est simple et directe.

Inconvénient:

le seul inconvénient est que votre navigateur bloque jusqu'à ce que toutes les données sont chargées ou un délai d'attente se produit. Comme pour l'application ajax en question, ce n'est pas vraiment un problème car l'application n'est d'aucune utilité jusqu'à ce que toutes les données initiales est chargé de toute façon.

Alternative?

cependant de nombreux navigateurs verrouiller toutes les fenêtres / onglets lorsque tandis que le javascript est occupé dans l'un d'eux, ce qui est un problème stupide de conception du navigateur - mais en conséquence le blocage sur le réseau peut-être lent obtient n'est pas poli si elle empêche les utilisateurs d'utiliser d'autres onglets en attendant ajax page à charger.

cependant, il semble que les get synchrones ont été supprimés ou restreints à partir de navigateurs récents de toute façon. Je ne suis pas sûr si c'est parce que quelqu'un a décidé qu'ils étaient juste toujours mauvais, ou si les rédacteurs de navigateur ont été confus par le projet de travail WC sur le sujet.

http://www.w3.org/TR/2012/WD-XMLHttpRequest-20120117/#the-open-method ne le fait pas ressembler (voir la section 4.7.3) vous n'êtes pas autorisé à définir un temps d'arrêt lorsque vous utilisez le mode de blocage. Cela me semble contre-intuitif: chaque fois que l'on bloque IO, il est poli de fixer un délai raisonnable, alors pourquoi permettre de bloquer io mais pas avec un délai spécifié par l'utilisateur?

mon opinion est que le blocage des IO a un rôle vital dans certaines situations mais doit être mis en œuvre correctement. Bien qu'il ne soit pas acceptable pour un onglet ou une fenêtre de navigateur de verrouiller tous les autres onglets ou fenêtres, c'est un défaut de conception du navigateur. Honte là où la honte est due. Mais il est parfaitement acceptable dans certains cas qu'un onglet ou une fenêtre ne réponde pas pendant quelques secondes (par exemple en bloquant IO/HTTP GET) dans certaines situations -- par exemple, sur la page de charge, peut-être que beaucoup de données doivent être avant que tout peut être fait de toute façon. Parfois le code de blocage correctement implémenté est le moyen le plus propre de le faire.

bien sûr la fonction équivalente dans ce cas peut être obtenue en utilisant http devient asynchrone, mais quelle sorte de routine stupide est nécessaire?

je suppose que j'essaierais quelque chose dans ce sens:

sur la charge de document, faire ce qui suit: 1: Mettre en place 6 variables globales de drapeau "Done", initialisées à 0. 2: Exécuter tous les 6 contexte obtient (en Supposant que l'ordre n'a pas d'importance)

ensuite, les callbacks d'achèvement pour chacun des 6 get http définiraient leurs drapeaux respectifs" Done". De plus, chaque rappel vérifierait tous les autres drapeaux done pour voir si tous les 6 HTTP gets ont été complétés. Le dernier rappel à compléter, après avoir vu que tous les autres avaient terminé, appellerait alors la vraie fonction init qui mettrait alors tout en place, maintenant que les données étaient toutes récupérées.

si l'ordre de la vérification importait -- ou si le serveur web n'était pas en mesure d'accepter plusieurs requêtes en même temps -- alors vous auriez besoin de quelque chose comme ceci:

in onload (), le premier http get être lancé. Dans son rappel, la seconde serait lancé. Dans son callback, le troisième -- et ainsi de suite, avec chaque callback lançant le prochain HTTP GET. Quand le dernier est revenu, alors il appellerait la vraie routine init ().

2
répondu Jesse Gordon 2013-12-31 21:19:56

XMLHttpRequest est traditionnellement utilisé pour les requêtes asynchrones. Parfois (pour le débogage, ou pour une logique d'entreprise spécifique), vous souhaitez modifier tous/plusieurs des appels asynchrones d'une page pour les synchroniser.

vous souhaitez le faire sans changer tout dans votre code JS. Le drapeau async/sync vous donne cette capacité, et si conçu correctement, vous n'avez besoin que de changer une ligne dans votre code / changer la valeur d'un var pendant le temps d'exécution.

2
répondu Itay Moav -Malimovka 2015-10-20 16:59:53

Firefox (et probablement tous les navigateurs non-IE) ne supporte pas async XHR timeOut.

  1. StackOverflow discussion
  2. Mozilla Firefox XMLHttpRequest

HTML5 les web workers , soutiennent les délais d'attente. Ainsi, vous pouvez vouloir envelopper la requête sync XHR à WebWorker avec timeout pour implémenter async-like XHR avec un comportement de timeout.

1
répondu Dmitry Kaigorodov 2017-05-23 12:02:27

je viens d'avoir une situation où des requêtes asynchrones pour une liste d'urls appelées successivement en utilisant forEach (et a pour boucle) provoqueraient l'annulation des requêtes restantes. Je suis passé au synchrone et ils fonctionnent comme prévu.

1
répondu AD Regan 2014-04-30 22:52:53

SYNC vs ASYNC: Quelle est la différence?

fondamentalement, il se résume à ceci:

console.info('Hello, World!');
doSomething(function handleResult(result) {
    console.info('Got result!');
});
console.info('Goodbye cruel world!');

quand doSomething est synchrone ceci imprimerait:

Hello, World!
Got result!
Goodbye cruel world!

en revanche, si doSomething est asynchrone , cela indiquerait:

Hello, World!
Goodbye cruel world!
Got result!

parce que la fonction doSomething fonctionne de manière asynchrone, il retourne avant que son travail soit terminé. Nous n'obtenons donc le résultat qu'après l'impression Goodbye cruel world!

si nous dépendons du résultat d'un appel asynch, nous devons placer le code correspondant dans le callback:

console.info('Hello, World!');
doSomething(function handleResult(result) {
    console.info('Got result!');
    if (result === 'good') {
        console.info('I feel great!');
    }
    else {
        console.info('Goodbye cruel world!');
    }
});

en tant que tel, Juste le fait que 2 ou 3 choses doivent se produire dans l'ordre n'est pas une raison pour les faire de manière synchrone (bien que le code sync soit plus facile pour la plupart des gens de travailler avec).

POURQUOI UTILISER XMLHTTPREQUEST SYNCHRONE?

Il ya des situations où vous avez besoin du résultat avant que la fonction appelée complète. Considérez ce scénario:

function lives(name) {
    return (name !== 'Elvis');
}
console.info('Elvis ' + (lives('Elvis') ? 'lives!' : 'has left the building...');

supposons que nous n'ayons aucun contrôle sur le code appelant (la ligne console.info ) et que nous devions changer la fonction lives pour demander au serveur... Il n'y a aucun moyen que nous puissions faire une requête async au serveur à partir de lives et avoir toujours notre réponse avant lives complète. Donc nous ne saurions pas s'il faut retourner true ou false . La seule façon d'obtenir le résultat avant la fonction complète est de faire un synchrone demande.

comme Sami Samhuri mentionne dans sa réponse, un scénario très réel où vous pourriez avoir besoin d'une réponse à votre demande de serveur avant la fin de votre fonction est l'événement onbeforeunload , car c'est la dernière fonction de votre application qui sera jamais fonctionner avant la fenêtre étant fermé.

JE N'AI PAS BESOIN D'APPELS DE SYNCHRONISATION, MAIS JE LES UTILISE QUAND MÊME CAR ILS SONT PLUS FACILES

Non. Des appels synchrones verrouillent votre navigateur et rendent l'application insensible. Mais vous avez raison. Le code asynchrone est plus dur. Il y a cependant un moyen de le traiter beaucoup plus facilement. Pas aussi facile que le code sync, mais il se rapproche: Promise S.

voici un exemple: deux les appels asynch devraient tous deux être complétés avec succès avant qu'un troisième segment de code puisse s'exécuter:

var carRented = rentCar().then(function(car){
  gasStation.refuel(car);
});

var hotelBooked = bookHotel().then(function(reservation) {
  reservation.confirm();
});

Promise.all([carRented, hotelBooked]).then(function(){
  // At this point our car is rented and our hotel booked.
  goOnHoliday();
});

Voici comment mettre en œuvre bookHotel :

function bookHotel() {
  return new Promise(function(resolve, reject){
    if (roomsAvailable()) {
      var reservation = reserveRoom();
      resolve(reservation);
    }
    else {
      reject(new Error('Could not book a reservation. No rooms available.'));
    }
  });
}

Voir aussi: Mieux Écrire du JavaScript avec des Promesses .

1
répondu Stijn de Witt 2015-07-24 12:52:13

voilà une bonne raison. Je voulais faire une requête http puis, en fonction du résultat, appeler click() sur un type d'entrée=fichier. Cela n'est pas possible avec l'asynchrone xhr ou fetch. Le callback perd le contexte "user action", donc l'appel click() est ignoré. XHR synchrone a sauvé mon bacon.

onclick(event){
    //here I can, but I don't want to.
    //document.getElementById("myFileInput").click();
    fetch("Validate.aspx", { method : "POST", body: formData, credentials: "include" })
    .then((response)=>response.json())
    .then(function (validResult) {
        if (validResult.success) {
            //here, I can't.
            document.getElementById("myFileInput").click();
        }
    });
}
0
répondu bbsimonbb 2018-01-23 13:10:54