Il semble que presque tout le monde fasse des requêtes asynchrones avec XMLHttpRequest, mais évidemment le fait qu'il y ait la possibilité de faire des requêtes synchrones indique qu'il pourrait y avoir une raison valable de le faire. Alors, quelle pourrait être cette raison valable?
javascript
ajax
Darrell Brogdon
la source
la source
Réponses:
Je pense qu'ils pourraient devenir plus populaires à mesure que les normes HTML 5 progressent. Si une application Web a accès à des travailleurs Web, je pourrais prévoir que les développeurs utilisent un travailleur Web dédié pour faire des requêtes synchrones, comme l'a dit Jonathan, pour s'assurer qu'une demande se produit avant une autre. Avec la situation actuelle d'un thread, c'est une conception loin d'être idéale car elle se bloque jusqu'à ce que la demande soit complète.
la source
Les XHR synchrones sont utiles pour enregistrer les données utilisateur. Si vous gérez l'
beforeunload
événement, vous pouvez télécharger des données sur le serveur lorsque l'utilisateur ferme la page.Si cela était fait à l'aide de l'option async, la page pourrait se fermer avant la fin de la demande. Faire cela de manière synchrone garantit que la demande se termine ou échoue de la manière attendue.
la source
Mettre à jour:
Ce qui suit a laissé entendre - mais n'a pas réussi à fournir - qu'avec l'avènement d'une meilleure gestion des demandes asynchrones, il n'y a vraiment aucune raison d'utiliser des demandes 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 demande soit complète - semble malveillant: )
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 produise avant qu'un utilisateur quitte une page, ou avant qu'une action ne soit effectuée - bloquer l'exécution d'autres codes (par exemple, empêcher le bouton de retour) pourrait réduire éventuellement les erreurs / la maintenance pour un système mal conçu; cela dit, je ne l'ai jamais vu dans la nature et je souligne qu'il faut l'éviter.
Les bibliothèques, comme la promesse , simulent la synchronicité en enchaînant les processus via des rappels. Cela convient à la majorité des besoins de développement où le désir est d'avoir des événements ordonnés et non bloquants qui permettent aux navigateurs de conserver une réactivité pour l'utilisateur (bonne UX).
Comme indiqué dans la documentation de Mozilla, il y a des cas où vous devez utiliser des requêtes synchrones; cependant, une solution de contournement qui utilise la balise (non disponible dans IE / Safari) pour de tels cas est également répertoriée . Bien que ce soit expérimental, si jamais il atteint l'acceptation des normes, il pourrait éventuellement mettre un clou dans le cercueil de la demande synchrone.
Vous voudriez effectuer des appels synchrones dans n'importe quel type de traitement de type transaction, ou partout où un ordre d'opération est nécessaire.
Par exemple, disons que vous souhaitez 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, le morceau ne sera jamais lu. Cela nécessite la synchronisation des requêtes.
Une autre raison serait lorsque vous travaillez avec un WebService, en particulier lors de l'exécution de maths sur le serveur.
Il y a très peu de fois qu'un appel synchrone peut être justifié dans un exemple courant du monde réel. Peut-être en cliquant sur Connexion, puis en cliquant sur une partie du site nécessitant la connexion d'un utilisateur.
Comme d'autres l'ont dit, cela liera votre navigateur, alors évitez-le là où vous le pouvez.
Au lieu d'appels synchrones, cependant, les utilisateurs souhaitent souvent arrêter un événement en cours de chargement et effectuer une autre opération. Il s'agit en quelque sorte de la synchronisation, puisque le premier événement est arrêté avant le début du second. Pour ce faire, utilisez la méthode abort () sur l'objet de connexion xml.
la source
Je dirais que si vous envisagez de bloquer le navigateur de l'utilisateur pendant que la demande se termine de manière acceptable, utilisez une demande synchrone.
Si la sérialisation des demandes est votre objectif, cela peut être accompli à l'aide de demandes asynchrones, en faisant en sorte que le rappel onComplete de votre demande précédente déclenche la suivante.
la source
Il existe de nombreux cas réels où le blocage de l'interface utilisateur est exactement le comportement souhaité.
Prenez une application avec plusieurs champs et certains champs doivent être validés par un appel xmlhttp à un serveur distant fournissant en entrée la valeur de ce champ et d'autres valeurs de champs.
En mode synchrone, la logique est simple, le blocage subi par l'utilisateur est très court et il n'y a pas de problème.
En mode asynchrone, l'utilisateur peut modifier les valeurs de tous les autres champs pendant que le champ initial 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 a échoué? Pur désordre. Si le mode de synchronisation devient obsolète et interdit, la logique de l'application devient un cauchemar à gérer. Fondamentalement, l'application doit être réécrite pour gérer les verrous (par exemple, désactiver d'autres éléments pendant les processus de validation). La complexité du code augmente considérablement. Le non-respect de cette consigne peut entraîner une défaillance de la logique et finalement une corruption des données.
Fondamentalement, la question est: qu'est-ce qui est le plus important, l'expérience d'interface utilisateur non bloquée ou le risque de corruption des données? La réponse doit rester avec le développeur de l'application, pas le W3C.
la source
Je peux voir une utilisation pour les requêtes XHR synchrones à utiliser lorsqu'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, j'implémente une telle requête XHR dans un petit sous-projet alors que les ressources JavaScript résident à des emplacements variables sur le serveur en fonction d'un ensemble de paramètres spécifiques. Les ressources JavaScript ultérieures reposent sur ces ressources variables et le chargement de ces fichiers DOIT être garanti avant que les autres fichiers dépendants ne soient chargés, ce qui rend l'application complète.
Cette idée de base s'étend vraiment en quelque sorte sur la réponse de vol7ron. Les procédures basées sur les transactions sont vraiment le seul moment où des demandes synchrones doivent être effectuées. 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, certaines fonctionnalités peuvent être verrouillées sur des "utilisateurs non autorisés" jusqu'à ce qu'ils se soient connectés en soi. 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 à ce sujet: 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 les appels synchrones. Lors de la mise en œuvre de requêtes synchrones, elles doivent être effectuées de manière à ce que le navigateur soit normalement verrouillé, de toute façon, par exemple dans la section HEAD avant le chargement de la page.
la source
À partir de 2015, les applications javascript de bureau sont de plus en plus populaires. Habituellement, dans ces applications, lors du chargement de fichiers locaux (et leur chargement à l'aide de XHR est une option parfaitement valide), la vitesse de chargement est si rapide qu'il n'y a guère d'intérêt à surcharger le code avec async. Bien sûr, il peut y avoir des cas où l'async est la voie à suivre (demande de contenu sur Internet, chargement de très gros fichiers ou d'un grand nombre de fichiers en un seul lot), mais sinon la synchronisation fonctionne très bien (et est beaucoup plus facile à utiliser) .
la source
jQuery utilise AJAX synchrone en interne dans certaines circonstances. Lors de l'insertion de code HTML contenant des scripts, le navigateur ne les exécutera pas. Les scripts doivent être exécutés manuellement. Ces scripts peuvent attacher des gestionnaires de clics. Supposons qu'un utilisateur clique sur un élément avant que le gestionnaire ne soit attaché et que la page ne fonctionne pas comme prévu. Par conséquent, pour éviter les conditions de concurrence, AJAX synchrone serait utilisé pour récupérer ces scripts. Parce que AJAX synchrone bloque efficacement tout le reste, il peut être sûr que les scripts et les événements s'exécutent dans le bon ordre.
la source
Que se passe-t-il si vous effectuez un appel synchrone dans le code de production?
Le ciel tombe.
Non sérieusement, l'utilisateur n'aime pas un navigateur verrouillé.
la source
Je l'utilise pour valider un nom d'utilisateur, lors de la vérification que le nom d'utilisateur n'existe pas déjà.
Je sais qu'il serait préférable de le faire de manière 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 vrai ou faux, selon que les données sont valides.
Puisque la fonction doit revenir, je ne peux pas utiliser de techniques asynchrones, donc je fais juste cela synchrone et j'espère que le serveur répondra assez rapidement pour ne pas être trop perceptible. Si j'utilisais un callback AJAX, alors je devrais gérer le reste de l'exécution différemment des autres méthodes de validation.
la source
false
) et le définir simplement sur true ou false lorsque le serveur répond. lors du changement de champ, vous réinitialisez l'indicateur et appelez à nouveau le serveur.Parfois, vous avez une action qui dépend des autres. Par exemple, l'action B ne peut être lancée que si A est terminé. L'approche synchrone est généralement utilisée pour éviter les conditions de course . Parfois, l'utilisation d'un appel synchrone est une implémentation plus simple, puis la création d'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 «bloquez» le navigateur de l'utilisateur jusqu'à ce que l'action soit terminée (jusqu'à ce que la requête retourne, se termine, se charge, etc.). Soyez donc prudent lorsque vous l'utilisez.
la source
J'utilise des appels synchrones lors du développement de code - tout ce que vous avez fait pendant que la requête se rendait et sortait du serveur peut masquer la cause d'une erreur.
Quand cela fonctionne, je le rends asynchrone, mais j'essaie d'inclure une minuterie d'abandon et des rappels d'échec, car on ne sait jamais ...
la source
Raison:
Disons que vous avez une application ajax qui a besoin de faire une demi-douzaine de http pour charger diverses données du serveur avant que l'utilisateur ne puisse faire une interaction.
Évidemment, vous voulez que cela soit déclenché à partir du chargement.
Les appels synchrones fonctionnent très bien pour cela sans aucune complexité supplémentaire au code. C'est simple et direct.
Inconvénient:
Le seul inconvénient est que votre navigateur se verrouille jusqu'à ce que toutes les données soient chargées ou qu'un délai d'attente se produise. Quant à l'application ajax en question, ce n'est pas vraiment un problème car l'application ne sert à rien tant que toutes les données initiales ne sont pas chargées de toute façon.
Alternative?
Cependant, de nombreux navigateurs verrouillent toutes les fenêtres / onglets lorsque le javascript est occupé dans l'un d'entre eux, ce qui est un problème de conception de navigateur stupide - mais par conséquent, le blocage sur un réseau éventuellement lent n'est pas poli s'il empêche les utilisateurs d'utiliser d'autres onglets en attendant le chargement de la page ajax.
Cependant, il semble que les obtentions synchrones aient de toute façon été supprimées ou restreintes des navigateurs récents. Je ne sais pas si c'est parce que quelqu'un a décidé qu'ils étaient toujours mauvais, ou si les écrivains de navigateur étaient confus par le brouillon de travail de WC sur le sujet.
http://www.w3.org/TR/2012/WD-XMLHttpRequest-20120117/#the-open-method donne l'impression que (voir section 4.7.3) vous n'êtes pas autorisé à définir un délai lors de l'utilisation du mode de blocage . Cela me semble contre-intuitif: chaque fois que l'on bloque IO, il est poli de définir un délai d'attente raisonnable, alors pourquoi autoriser le blocage de io mais pas avec un délai spécifié par l'utilisateur?
Mon opinion est que le blocage des E / S a un rôle vital dans certaines situations mais doit être mis en œuvre correctement. Bien qu'il ne soit pas acceptable qu'un onglet ou une fenêtre du navigateur verrouille 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 individuel ne réponde pas pendant quelques secondes (c'est-à-dire en utilisant le blocage d'E / S / HTTP GET) dans certaines situations - par exemple, lors du chargement de la page, peut-être beaucoup de données doit l'être avant que quoi que ce soit puisse être fait de toute façon. Parfois, un code de blocage correctement implémenté est le moyen le plus propre de le faire.
Bien sûr, une fonction équivalente dans ce cas peut être obtenue à l'aide de http get asynchrones, mais quelle sorte de routine loufoque est nécessaire?
Je suppose que j'essaierais quelque chose du genre:
Lors du chargement du document, procédez comme suit: 1: Configurez 6 variables d'indicateur globales "Terminé", initialisées à 0. 2: Exécutez les 6 récupérations d'arrière-plan (en supposant que l'ordre n'a pas d'importance)
Ensuite, les rappels d'achèvement pour chacun des 6 http get's définiraient leurs indicateurs respectifs «Done». En outre, chaque rappel vérifierait tous les autres indicateurs de fin pour voir si les 6 obtentions HTTP étaient terminées. Le dernier rappel à terminer, en voyant que tous les autres étaient terminés, appellerait alors la fonction REAL init qui mettrait alors tout en place, maintenant que toutes les données étaient extraites.
Si l'ordre de la récupération importait - ou si le serveur Web était incapable d'accepter plusieurs requêtes en même temps - alors vous auriez besoin de quelque chose comme ceci:
Dans onload (), le premier http get serait lancé. Dans son rappel, le second serait lancé. Dans son rappel, le troisième - et ainsi de suite, chaque rappel lançant le prochain HTTP GET. Lorsque le dernier revenait, il appellerait la vraie routine init ().
la source
SYNC vs ASYNC: Quelle est la différence?
En gros, cela se résume à ceci:
Quand
doSomething
est synchrone cela imprimerait:En revanche, si
doSomething
est asynchrone , cela afficherait:Étant donné que la fonction
doSomething
effectue son travail de manière asynchrone, elle retourne avant que son travail ne soit terminé. On n'obtient donc le résultat qu'après impressionGoodbye cruel world!
Si nous dépendons du résultat d'un appel asynchrone, nous devons placer le code dépendant dans le rappel:
En tant que tel, le simple fait que 2 ou trois choses doivent se produire dans l'ordre n'est pas une raison de les faire de manière synchrone (bien que le code de synchronisation soit plus facile pour la plupart des gens à travailler).
POURQUOI UTILISER SYNCHRONOUS XMLHTTPREQUEST?
Dans certaines situations, vous avez besoin du résultat avant la fin de la fonction appelée. Considérez ce scénario:
Supposons que nous n'ayons aucun contrôle sur le code appelant (la
console.info
ligne) et que nous devions changer de fonctionlives
pour demander au serveur ... Il n'y a aucun moyen que nous puissions faire une requête asynchrone au serveur de l'intérieurlives
et avoir toujours notre réponse avant lalives
fin. Nous ne saurions donc pas s'il faut revenirtrue
oufalse
. La seule façon d'obtenir le résultat avant la fin de la fonction est de faire une requête synchrone.Comme l'
Sami Samhuri
indique sa réponse, un scénario très réel dans lequel vous pourriez avoir besoin d'une réponse à votre demande de serveur avant la fin de votre fonction est l'onbeforeunload
événement, car c'est la dernière fonction de votre application qui s'exécutera avant la fermeture de la fenêtre.JE N'AI PAS BESOIN D'APPELS DE SYNCHRONISATION, MAIS JE LES UTILISE DE TOUTE MANIÈRE COMME ILS SONT PLUS FACILES
Veuillez ne pas le faire. Les appels synchrones verrouillent votre navigateur et font que l'application ne répond pas. Mais tu as raison. Le code async est plus difficile. Il existe cependant un moyen de faciliter le traitement. Pas aussi simple que le code de synchronisation, mais ça se rapproche: promesses .
Voici un exemple: Deux appels asynchrones doivent tous deux se terminer avec succès avant qu'un troisième segment de code puisse s'exécuter:
Voici comment vous implémenteriez
bookHotel
:Voir aussi: Ecrire un meilleur JavaScript avec des promesses .
la source
XMLHttpRequest
est traditionnellement utilisé pour les requêtes asynchrones. Parfois (pour le débogage ou une logique métier spécifique), vous souhaitez modifier tous / plusieurs des appels asynchrones dans une page à synchroniser.Vous aimeriez le faire sans tout changer dans votre code JS. L'indicateur async / sync vous donne cette capacité, et s'il est conçu correctement, vous n'avez besoin que de changer une ligne dans votre code / changer la valeur d'un
var
pendant l'exécution.la source
Firefox (et probablement tous les navigateurs non-IE) ne prend pas en charge async XHR timeOut.
HTML5 WebWorkers prend en charge les délais d' expiration . Par conséquent, vous souhaiterez peut-être encapsuler la requête XHR de synchronisation vers WebWorker avec un délai d'expiration pour implémenter un XHR de type asynchrone avec un comportement de délai d'expiration.
la source
Je viens d'avoir une situation où des demandes asynchrones pour une liste d'urls appelées successivement en utilisant forEach (et une boucle for) entraîneraient l'annulation des demandes restantes. Je suis passé à synchrone et ils fonctionnent comme prévu.
la source
L'utilisation de requêtes HTTP synchrones est une pratique courante dans le secteur de la publicité mobile.
Les entreprises (également appelées «éditeurs») qui créent des applications diffusent souvent des annonces pour générer des revenus. Pour cela, ils installent des SDK publicitaires dans leur application. Beaucoup existent (MoPub, Ogury, TapJob, AppNext, Google Ads AdMob).
Ces SDK diffuseront des annonces dans une vue Web.
Lorsque vous diffusez une annonce à un utilisateur, l' expérience doit être fluide , en particulier lors de la lecture d'une vidéo. Il ne devrait y avoir aucune mise en mémoire tampon ou chargement à tout moment.
Pour résoudre ceci
precaching
est utilisé. Où les médias (image / vidéos / etc.) sont chargés de manière synchrone en arrière-plan de la vue Web.Pourquoi ne pas le faire de manière asynchrone?
onload
événement pour savoir quand l'annonce est "prête" à être diffusée à l'utilisateurAvec la dépréciation des XMLHttpRequests synchrones , les entreprises de publicité seront très probablement obligées de changer la norme à l'avenir, à moins qu'une autre manière ne puisse être déterminée.
la source
Synchronous XHR peut être très utile pour le développement d'outils internes (hors production) et / ou de framework. Imaginez, par exemple, que vous vouliez charger une bibliothèque de code de manière synchrone lors du premier accès, comme ceci:
Avant de vous mettre dans le pétrin et de régurgiter aveuglément le mal de l'évaluation, gardez à l'esprit que ce n'est que pour des tests locaux. Pour les versions de production, _draw serait déjà défini.
Donc, votre code pourrait ressembler à ceci:
Ce n'est qu'un exemple de quelque chose qui serait impossible à faire sans la synchronisation XHR. Vous pouvez charger cette bibliothèque à l'avance, oui, ou faire une promesse / un rappel, mais vous ne pouvez pas charger la bibliothèque de manière synchrone sans synchronisation XHR. Pensez à combien ce type de chose pourrait nettoyer votre code ...
Les limites de ce que vous pouvez faire avec cela pour les outils et les frameworks (exécutés localement) ne sont limitées que par votre imagination. Cependant, il semble que l'imagination soit un peu limitée dans le monde JavaScript.
la source
Eh bien, voici une bonne raison. Je voulais faire une requête http puis, en fonction du résultat, appelez click () sur une entrée type = fichier. Cela n'est pas possible avec xhr ou fetch asynchrone. Le rappel perd le contexte "action utilisateur", donc l'appel click () est ignoré. Synchronous xhr a sauvé mon bacon.
la source