Javascript ne passe pas de manière aynchrone au-delà d’un appel AJAX

Lorsque l’utilisateur appuie sur le bouton “Processus” de mon application, je souhaite que l’application déclenche une demande AJAX, puis redirige immédiatement l’utilisateur vers un autre écran sans attendre les résultats de la demande AJAX. Je crois l’avoir codé correctement mais je remarque que l’écran attend que AJAX soit terminé avant de redirect. Est-ce que je manque quelque chose en dessous?

$('#process-btn').on('click', function() { // disable the process & cancel buttons to prevent // double submission or interruption $('#cancel-btn').addClass('disabled'); $(this).addClass('disabled'); // sortinggger the AJAX require to process the uploaded file on the server side $.ajax({ url: $('#form').attr('action'), type: 'post', data: $('#form').serialize(), success: function() { //on success } }); // redirect the user to view list // this line is not being called immediately - // this is being called only after AJAX returns window.location.replace( www_root + 'Home/index' ); }); 

Parce que le bouton auquel vous avez accroché ce gestionnaire est un bouton d’envoi pour un formulaire (selon vos commentaires) et que vous n’empêchez pas le comportement par défaut de ce bouton, le formulaire d’envoi se produira immédiatement et, lorsque l’envoi sera renvoyé, il changera. la page indépendamment de ce que votre code essaie de faire.

Le problème est donc que le formulaire renvoyé, soumis, surmontait ce que votre code essayait de faire.


Vous vivez peut-être un peu dangereusement en redirigeant avant la fin de votre appel ajax. Il est possible que le navigateur puisse abandonner la connexion ajax avant que les tampons TCP aient été envoyés, car TCP a souvent un petit délai avant l’envoi des tampons afin de collecter des données consécutives dans des paquets communs. Il serait beaucoup plus sûr de redirect après un court délai ou de redirect l’événement complete qui sera appelé indépendamment du succès de l’ajax.


Si vous voulez vraiment faire la redirection AVANT que l’appel ajax soit terminé, vous pouvez essayer la valeur de délai d’attente (indiquée ici comme étant définie sur 500 ms) dans ce code pour voir ce qui fonctionne de manière fiable dans plusieurs navigateurs:

 $('#process-btn').on('click', function(e) { // prevent default form post e.preventDefault(); // disable the process & cancel buttons to prevent // double submission or interruption $('#cancel-btn').addClass('disabled'); $(this).addClass('disabled'); // sortinggger the AJAX require to process the uploaded file on the server side $.post($('#form').attr('action'), $('#form').serialize()); // redirect the user to view list // this being called after a short delay to "try" // to get the form ajax call sent, but not "wait" for the server response setTimeout(function() { window.location.replace( www_root + 'Home/index' ); }, 500); }); 

Notez également que j’ai ajouté un e.preventDefault() et l’argument e au gestionnaire d’événements pour m’assurer que le formulaire n’est pas posté par défaut, uniquement par votre code ajax.

Et, le délai d’attente est réglé ici à 500 ms. Vous avez besoin de suffisamment de temps pour que l’infrastructure TCP de l’ordinateur hôte envoie toutes vos données de formulaire avant de lancer la redirection. Je vois une mention d’un “téléchargement de fichier” dans vos commentaires. Si ce formulaire est en train de télécharger un fichier, cela peut prendre plus de 500 ms. S’il ne s’agit que d’envoyer quelques champs de formulaire, cela devrait aller assez vite en supposant qu’il n’y ait pas de problème de connexion.

Mise en garde: le faire de cette manière n’est pas le moyen 100% fiable d’obtenir des données sur votre serveur. Il peut facilement y avoir des situations où il faut plus de temps que d’habitude pour effectuer une recherche DNS avant de se connecter à votre serveur, ou votre serveur pourrait prendre temporairement plus de temps pour répondre à la connexion initiale avant que des données ne puissent lui être envoyées. Le seul moyen fiable à 100% est d’attendre que l’appel ajax soit un succès, comme mentionné ailleurs.

Vous pourriez peut-être avoir le meilleur des deux mondes (fiabilité + réponse rapide) si vous modifiez la manière dont votre serveur traite l’appel ajax afin que, dès qu’il ait reçu les données, il renvoie une réponse réussie (par exemple, en millisecondes après la réception des données). ) et ensuite, après avoir renvoyé la réponse réussie afin que le navigateur puisse ensuite faire sa redirection de manière fiable, il faut compter 2-3 minutes pour traiter les données. N’oubliez pas que vous n’avez pas attendu jusqu’à ce que vous ayez terminé le traitement de la demande de réponse. Ensuite, vous savez que le serveur a reçu les données, mais le navigateur n’a pas à attendre le temps de traitement. Si vous ne voulez pas toujours que cet appel ajax fonctionne de cette façon, vous pouvez passer un argument à l’appel ajax pour indiquer au serveur si vous souhaitez une réponse rapide ou non.

Pourquoi ne pas essayer ceci:

  $.ajax({ url: $('#form').attr('action'), type: 'post', data: $('#form').serialize(), success: function() {window.location.replace( www_root + 'Home/index' );} });