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


87

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?


1
C'est une très bonne question! Je ne pense pas que la réponse sera très intéressante, mais une excellente question néanmoins. Avez-vous essayé un appel synchrone pour voir ce qui va se passer?
Tad Donaghe

3
Les appels synchrones bloquent le navigateur, ce qui entraîne une expérience utilisateur terrible. Ainsi ma question. Je ne pouvais penser à aucune bonne raison de l'utiliser.
Darrell Brogdon

2
Réponse semi-sérieuse: peut-être simplement pour remplir le chapitre qui précède les requêtes asynchrones dans le livre JavaScript que vous lisez.
Ben James

Personnellement, j'aimerais utiliser un ajax syncron pour encapsuler plusieurs appels à des fonctions côté serveur sans avoir à écrire une requête pour chaque appel.
Paul Ishak

exécuter du code localement, en particulier pour les frameworks et outils de développement internes.
user2800679 le

Réponses:


25

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.


16
Je suppose qu'il voulait dire `` Web Workers ''
evilpie

Je pense que le point distillé. Dans UI Thread, créez un thread ou une tâche asynchrone. Si dans le thread déjà, utilisez synchronisé dans la plupart des cas. Les discussions sont beaucoup plus «adaptées aux blocs»
HAMMeReD

C'est une vieille réponse, mais ce commentaire s'applique même à l'époque, même avant HTML5, les navigateurs fournissaient 2 threads pour faire des requêtes. J'ai écrit un script de pool de connexions pour utiliser les deux, car même avec une requête asynchrone, avec une seule connexion, vous pouvez lier le navigateur. L'utilisation des deux permet de pousser / tirer plus de données à travers la ligne; mais iirc, je pense que les demandes de synchronisation bloquent toujours le navigateur.
vol7ron

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.
Dmitry Kaigorodov

1
-1. Ce n'est pas vraiment une réponse et toute la discussion sur les fils ne fait que semer la confusion. La réponse ci-dessous par Sami est en fait bien meilleure.
Stijn de Witt

30

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.


4
Édité: Je me rends compte que vous venez de déposer du txt d'un utilisateur HN paresseux, mais un peu de temps pour le formuler est bien apprécié ici sur SO.
Frank Krueger

Mais en fait, c'est la seule raison valable que j'ai vue jusqu'à présent.
Stijn de Witt

@Frank Krueger Qu'est-ce que HN?
Douglas a tenu

1
@DouglasHeld Un site Web appelé Hacker News à news.ycombinator.com
Sami Samhuri

13

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.

Exemple: le serveur a une variable avec la valeur 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 et non 8; l'ordre de fonctionnement est donc important et la synchronisation est nécessaire.


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.


1
Je pense que cela devrait être la vraie réponse

3
@Zack: c'est un bon exemple, mais vous pourriez probablement faire la même chose avec des appels asynchrones en fonction de l'événement qui l'appelle.
vol7ron

3
+1 Il existe un cas valide selon lequel des conditions de concurrence logiques peuvent résulter de requêtes de serveur asynchrones ... Cependant, la solution ne doit pas nécessairement être la synchronicité. À moins que vos demandes ne soient gérées par un Web Worker, il serait préférable d'écrire une couche de transport qui numéroterait les demandes, puis garantirait que les opérations sont traitées dans l'ordre des ID de demande.
Roy Tinker

3
-1 Le traitement des transactions est un exemple parfait où vous devez utiliser la garantie que les choses échouent ou réussissent - ce n'est pas parce que la commande est synchrone que la première demande a réussi ... vous avez compté sur la réponse qui vous le dit. Dans cet exemple, vous feriez la deuxième requête uniquement à partir du gestionnaire de résultats de la première requête - auquel cas ils pourraient tout aussi bien être asynchrones.
Mathew

2
@Mathew: cela n'est vrai que si votre processus de type transaction dépend du résultat de l'action qui le précède. Si vous avez un bouton qui crée un nouvel objet (récupéré sur le serveur) dans votre page; s'il était asynchrone, l'utilisateur pourrait potentiellement cliquer plusieurs fois et renvoyer de nombreux objets. Un appel synchrone empêcherait cela et n'autoriserait la création d'un autre nouvel objet qu'après la fin du premier, qu'il soit erroné ou non. S'il vous plaît attention à libellé, je l' ai fait transaction comme et non transaction sur le but.
vol7ron

8

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.


1
Hmm, j'ajouterais une fenêtre glissante à cela, sinon vous perdrez essentiellement le temps d'aller-retour pour chaque demande
Stephan Eggermont

7

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.


1
Je pense que vous confondez l'idée de bloquer l'interaction de l'utilisateur avec le blocage du fil de discussion du navigateur. Il existe un milliard de moyens simples pour empêcher l'utilisateur de continuer à interagir avec une entité donnée (champ de formulaire, etc.) pendant un appel asynchrone qui ne nécessiterait pas de bloquer le thread du navigateur. Lorsque le thread se bloque, il ne peut y avoir aucun traitement logique, et c'est juste une mauvaise situation; il crée beaucoup plus de problèmes / problèmes potentiels, qui sont pratiquement insolubles, qu'il n'en résout.
Luke Chavers

6

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.


Le fait qu'une action repose sur le résultat d'une autre action n'est pas une raison pour effectuer cette autre action de manière synchrone. Vous n'avez besoin d'un appel synchrone que si le résultat d'une action doit être traité avant la fin de la fonction appelante .
Stijn de Witt

5

À 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) .


C'est en fait la situation dans laquelle je me trouve et c'est 2020. J'ai une application de bureau qui affiche son interface utilisateur via HTTP afin que vous puissiez y accéder à partir d'un navigateur fonctionnant sur la machine locale ou même sur le réseau. Dans ces scénarios, le réseau est rapide et fiable, donc faire des requêtes XHR synchrones est un excellent moyen de garder le code simple. La plupart des gens ne réalisent pas que les requêtes asynchrones XHR sont comme utiliser des threads et que cela peut devenir vraiment compliqué avec de nombreuses opportunités de bogues.
Eric Mutta

4

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.


2

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é.


2
La question est "pourquoi le faire avec XMLHTTPREQUEST" et non "pourquoi faire ou ne pas synchroniser les appels"
Itay Moav -Malimovka

1
Si vous ajoutez un délai d'attente raisonnable, cela ne devrait pas poser de problème.
Greg

1
Il demande des cas d'utilisation d'appels de synchronisation ... Pas pour leurs inconvénients (nous les connaissons tous maintenant ...)
Stijn de Witt

quel utilisateur? tous les utilisateurs sont-ils les mêmes? que diriez-vous des ingénieurs testant localement? ... donc accéder aux fichiers du système de fichiers avec très peu de retard ????
user2800679 le

2

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.


Une astuce dans un tel scénario consiste à laisser la fonction de validation vérifier simplement un indicateur (qui commence par 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.
Stijn de Witt

2

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 question est "pourquoi le faire avec XMLHTTPREQUEST" et non "pourquoi synchroniser les appels"
Itay Moav -Malimovka

L'auteur lui-même dit: « Les appels synchrones bloquent le navigateur, ce qui conduit à une expérience utilisateur terrible». dans un commentaire, donc tout le monde dans ce fil a postulé pour l'approche "appels synchrones". Pourquoi avez-vous pris cette compréhension littérale de la question si vous ne pouvez pas vraiment dire avec certitude ce que l'auteur voulait dire?
GmonC

2

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 ...


2

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 ().


2

SYNC vs ASYNC: Quelle est la différence?

En gros, cela se résume à ceci:

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

Quand doSomethingest synchrone cela imprimerait:

Hello, World!
Got result!
Goodbye cruel world!

En revanche, si doSomethingest asynchrone , cela afficherait:

Hello, World!
Goodbye cruel world!
Got result!

Étant donné que la fonction doSomethingeffectue 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:

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, 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:

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 console.infoligne) et que nous devions changer de fonction livespour demander au serveur ... Il n'y a aucun moyen que nous puissions faire une requête asynchrone au serveur de l'intérieur liveset avoir toujours notre réponse avant la livesfin. Nous ne saurions donc pas s'il faut revenir trueou false. 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 Samhuriindique 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:

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 vous implémenteriez 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: Ecrire un meilleur JavaScript avec des promesses .


1
"Merci de ne pas le faire. Les appels synchrones verrouillent votre navigateur et empêchent l'application de répondre" Ce n'est pas toujours un problème. Imaginez que vous testez localhost et que vous êtes un développeur.
user2800679 le

2

XMLHttpRequestest 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 varpendant l'exécution.



1

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.


1

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 precachingest 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?

  1. Cela fait partie d'une norme mondialement acceptée
  2. Le SDK écoute l' onloadévénement pour savoir quand l'annonce est "prête" à être diffusée à l'utilisateur

Avec 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.


0

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:

get draw() 
{
    if (!_draw)
    {
       let file;
       switch(config.option)
       {
           case 'svg':
              file = 'svgdraw.js';
              break;
           case 'canvas':
              file = 'canvasdraw.js';
              break;
           default:
              file = 'webgldraw.js';
       }

       var request = new XMLHttpRequest();
       request.open('GET', file, false);
       request.send(null);
       _draw = eval(request.responseText);
    }

    return _draw;
}

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:

foo.drawLib.draw.something(); //loaded on demand

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.


-1

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.

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

save it on a var
Es Noguera
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.