Il y a quelques jours, j'ai posé cette question :
Je lance six requêtes ajax asynchrones jQuery sur la même action de contrôleur, presque toutes en même temps. Chaque requête met 10 secondes à revenir.
En déboguant et en enregistrant les requêtes de la méthode d'action, je remarque que les requêtes sont sérialisées et ne s'exécutent jamais en parallèle, c'est-à-dire que je vois une ligne de temps dans mes journaux log4net comme ceci :
2010-12-13 13:25:06,633 \[11164\] INFO - Got:1156
2010-12-13 13:25:16,634 \[11164\] INFO - Returning:1156
2010-12-13 13:25:16,770 \[7124\] INFO - Got:1426
2010-12-13 13:25:26,772 \[7124\] INFO - Returning:1426
2010-12-13 13:25:26,925 \[11164\] INFO - Got:1912
2010-12-13 13:25:36,926 \[11164\] INFO - Returning:1912
2010-12-13 13:25:37,096 \[9812\] INFO - Got:1913
2010-12-13 13:25:47,098 \[9812\] INFO - Returning:1913
2010-12-13 13:25:47,283 \[7124\] INFO - Got:2002
2010-12-13 13:25:57,285 \[7124\] INFO - Returning:2002
2010-12-13 13:25:57,424 \[11164\] INFO - Got:1308
2010-12-13 13:26:07,425 \[11164\] INFO - Returning:1308
En regardant la chronologie du réseau dans FireFox, je vois ceci :
L'échantillon de journal ci-dessus et la chronologie du réseau Firefox concernent tous deux le même ensemble de demandes.
Les demandes de la même action à partir de la même page sont-elles sérialisées ? Je suis au courant de l'accès en série à la Session
dans la même session, mais aucune donnée de session n'est touchée.
J'ai réduit le code côté client à une seule requête (la plus longue) mais cela bloque toujours le navigateur, c'est-à-dire que le navigateur ne répond à un clic sur un lien que lorsque la requête ajax est terminée.
Ce que j'observe également ici (dans les outils de développement de Chrome), c'est que lorsque l'on clique sur un lien alors qu'une requête ajax longue durée est en cours d'exécution, un message d'erreur est généré. Failed to load resource
qui suggère que le navigateur a tué (ou tente de tuer et attend ?) la requête ajax :
Cependant, le navigateur met toujours un certain temps à rediriger vers la nouvelle page.
Les requêtes ajax sont-elles réellement asynchrones ou s'agit-il d'un tour de passe-passe parce que le javascript est en fait monofilaire ?
Mes demandes sont-elles trop longues pour que cela fonctionne ?
Le problème se produit également dans Firefox et IE.
J'ai aussi changé le script pour utiliser $.ajax
directement et explicitement fixé async: true
.
Je l'exécute sur IIS7.5, les versions Windows 2008R2 et Windows 7 font la même chose.
Les builds Debug et Release se comportent également de la même manière.
0 votes
Avez-vous testé cela dans firefox/IE. Peut-être est-ce un problème de chrome ?
0 votes
@aseem - c'est la même chose dans F/Fox et IE
0 votes
Peut-être que votre script change le paramètre asynchrone quelque part ailleurs.
0 votes
Pouvez-vous vérifier dans FF/Firebug quand les requêtes multiples sont envoyées (Net Panel dans firebug). Ces chronologies ne semblent pas correctes, les requêtes jquery ajax sont asynchrones et doivent être exécutées en parallèle.
0 votes
@aseem - J'ai mis à jour la question pour montrer un journal révisé et la chronologie correspondante de firefox.
0 votes
@anton - IIS7.5. @aseem - on ne peut pas fixer une prime pour deux jours.
0 votes
Si vous voulez bien regarder de plus près : 1913 est révisé avant 1912. 1308 est desservi avant 2002. Si le navigateur envoyait des requêtes synchrones, ce ne serait pas le cas.
0 votes
@aseem - la chronologie de firefox n'est pas dans l'ordre, je suppose que c'est parce que toutes les demandes sont placées simultanément et qu'il n'y a rien entre elles dans le temps. Mais si vous regardez l'ordre d'achèvement, il correspond à l'enregistrement dans l'action. Et l'enregistrement dans l'action montre que les demandes sont effectivement sérialisées.
0 votes
La chronologie de firebug est construite au fur et à mesure que les demandes sont envoyées. Elle est donc toujours séquentielle. Vous pouvez vérifier cela en développant un nœud et en vérifiant la date dans l'en-tête. Vous verrez que toutes les requêtes sont envoyées en même temps.
1 votes
@aseem - il n'y a pas de temps "envoyé" dans les en-têtes de la demande. Ce que je veux dire, c'est que parce qu'ils sont tous demandés en même temps, Firefox (ou Google) ne peut pas les trier dans un ordre raisonnable. L'ordre qui existe est dû au temps nécessaire à chaque XHR sous-jacent pour répondre et reconnaître que "oui, en effet, j'ai envoyé cette requête". Il peut donc y avoir quelques millisecondes de différence entre chacune d'elles en raison des différences dans l'établissement d'une connexion TCP/IP. D'où le décalage dans le temps. Cependant, je sais pertinemment que ces appels sont sérialisés (la journalisation dans l'action du contrôleur me le dit). .....cont...
0 votes
@aseem ...également si je n'ai qu'un Thread.Sleep() de 10 secondes (au lieu du code réel qui interroge nos services back-end), je vois à nouveau tous les appels sérialisés à la fois dans le navigateur et côté serveur. Chaque appel prend 10 secondes l'un après l'autre. Il n'y a pas d'exécution parallèle. Je m'attendrais au moins à ce que deux appels se terminent en même temps.
0 votes
@aseem - J'ai mis à jour la question avec les résultats d'une demande où j'ai introduit un délai de 0,1s entre chaque demande, juste pour donner à chaque demande XHR suffisamment de temps pour retourner un ack que la demande a été envoyée. Vous pouvez donc maintenant voir exactement ce qui se passe
0 votes
Je peux voir maintenant des trucs fous
0 votes
@aseem - c'est vraiment un peu fou.
0 votes
@Kev - c'est sans doute un peu bête, mais vos appels JS se trouvent-ils dans la fonction $(document).ready() ou ailleurs dans la page ? Je suppose que s'ils sont ailleurs, ils peuvent empêcher le navigateur de poursuivre le rendu, mais que $(document).ready() ne le ferait pas ou ne devrait pas le faire.
0 votes
Hector - ils sont là
$(document).ready()
.0 votes
@hector @aseem - jetez un coup d'oeil à ma réponse, quelque chose à surveiller.
0 votes
@Kev - merci d'avoir partagé la réponse. Je n'aurais jamais deviné cela et c'est définitivement quelque chose à surveiller.