2010-11-23 11 views
0

Je suis en train de supprimer une question précédemment posée et de demander à nouveau plus succinctement maintenant que j'ai un peu plus de compréhension du problème.AJAX: comment contourner le problème d'avoir besoin de requêtes synchrones?

J'ai une page qui utilise beaucoup d'AJAX et qui est mise à jour et remplie dynamiquement avec du contenu (éléments de formulaire et div avec du texte renvoyé par un autre élément de formulaire). J'ai vraiment besoin de pouvoir forcer les utilisateurs à attendre que les requêtes AJAX soient traitées (par exemple après avoir rempli un champ de texte qui a soumis certaines valeurs) avant de continuer. De ce que je comprends en utilisant des requêtes synchrones peut causer des problèmes avec le navigateur suspendu etc ...

J'ai également besoin d'une fonction javascript qui exécute plusieurs appels de fonction AJAX mais j'ai aussi besoin d'eux pour exécuter un à la fois. Actuellement, l'utilisation d'appels asynchrones produit des résultats imprévisibles ... peut-être que je vais à ce sujet dans le mauvais sens. Il y a beaucoup de code donc il est difficile de donner un petit exemple, mais je vais essayer ci-dessous:

Le dessous (qui est lui-même inséré par une fonction Ajax) ajoute dynamiquement plus d'éléments de forme à la page si C'est la première fois que l'entrée a été éditée (la première fois que le contenu est écrit dans la base de données ... il suffit de mettre à jour l'entrée db existante et je n'ai pas besoin d'ajouter les éléments de formulaire)

<form name='talkItemForm' id='talkItemFrom-<?php print $_POST[talkItemID]; ?>' class='talkItemForm' method='post'> 

    <input type='hidden' id='talkItemID' name='talkItemID' value='<?php print $_POST[talkItemID]; ?>'><input type='hidden' id='talkID' name='talkID' value='<?php print $_POST[talkID]; ?>'> 

    <input type='text' name='talkItemInput' id='talkItemInput' value='New Topic...' onblur=" updateTalkItem(this.parentNode, '<?php print $_POST[talkID]; ?>', '<?php print $_POST[talkItemID]; ?>'); isNewTalkItem('<?php print $_POST[talkID]; ?>', '<?php print $_POST[talkItemID]; ?>', '<?php print generateTalkItemID()+1; ?>','<?php print generateNoteID(); ?>'); "/> 

    </form> 

Invoque:

function isNewTalkItem (talkID, talkItemID, newTalkItemID, newNoteID){ 

     var url = "./wp-content/themes/twentyten/addBelowIfNew.php"; 

     var poststr = "talkItemID=" + talkItemID; 

     http_request = false; 
     if (window.XMLHttpRequest) { // Mozilla, Safari,... 
     http_request = new XMLHttpRequest(); 
     if (http_request.overrideMimeType) { 
      // set type accordingly to anticipated content type 
      //http_request.overrideMimeType('text/xml'); 
      http_request.overrideMimeType('text/html'); 
     } 
     } else if (window.ActiveXObject) { // IE 
     try { 
      http_request = new ActiveXObject("Msxml2.XMLHTTP"); 
     } catch (e) { 
      try { 
       http_request = new ActiveXObject("Microsoft.XMLHTTP"); 
      } catch (e) {} 
     } 
     } 
     if (!http_request) { 
     alert('Cannot create XMLHTTP instance'); 
     return false; 
     } 

     http_request.onreadystatechange = function(){ 


      if (http_request.readyState == 4) { 
       if (http_request.status == 200 || http_request.status == 0) { 

        result = http_request.responseText; 

     //following code will note execute if this is not the first time this field has been edited... 
     if (result) { 

         // call to AJAX function that inserts a new <form> 
      newNote(newNoteID, talkItemID); 

         // another call to AJAX function that inserts a new <form> 
      newTalkItem(talkItemID, talkID); 

     } 

       } else { 
        alert('There was a problem with the request.'); 
       } 

      } 

     }  

     http_request.open('POST', url, true); 
     http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 
     http_request.setRequestHeader("Content-length", poststr.length); 
     http_request.setRequestHeader("Connection", "close"); 
     http_request.send(poststr); 

Répondre

0

Lorsque j'ai regardé pour la première fois cette question, j'ai supposé à tort que vous utilisiez ajax. Comme l'a dit Mikhail, vous devriez vraiment apprendre cela, cela rend les choses beaucoup plus faciles, plus simples et plus propres.

Je pense que je peux répondre à peu près à vos deux questions avec des réponses similaires.

En ce qui concerne la première question, vous avez raison, faire des requêtes synchrones bloquera le processus du navigateur pendant qu'il attend le retour de la requête. Ce que vous pouvez faire, c'est soit faire en sorte que la partie suivante de l'interface utilisateur soit invisible pendant que vous attendez que les résultats reviennent ou la rendent non modifiable. Voici un exemple d'une requête ajax qui pourrait faire cela:

$ .ajax ({url: "test.html", contexte: document.body, succès: function() { // Rendre ui modifiable }});

De même, pour votre deuxième question, vous pouvez simplement les nids:

.ajax $ ({url: "test.html", le contexte: document.body, succès: function() {

$.ajax({ url: "test.html", context: document.body, success: function(){ 

     $.ajax({ url: "test.html", context: document.body, success: function(){ 

      $(this).addClass("done"); 

     }}); 

    }}); 

}});

+0

ahhh ... c'est génial. je vais essayer. Merci. Je connais un peu le sujet de jquery, donc je vais mettre en place un ajax avec ça aussi. Je suis juste coincé dans le développement d'une application web comme un projet de compagnie. Stack Overflow est une ressource incroyable. Je ferai de mon mieux pour contribuer (sur des choses que je connais un peu :) merci les gars. J'avais besoin d'un peu de conseil/perspective ici aussi. ma tête est tellement pleine de fonctions php et javascript et de variables et de requêtes et de réponses et de tables de base de données que je ne pouvais pas voir le bois pour les arbres. Merci encore. ... bien que je puisse encore être de retour :) –

1

Il peut y avoir une meilleure ap Pour résoudre votre tâche globale, mais plusieurs points peuvent être faits indépendamment:

  1. Apprenez jquery et utilisez-le pour votre syntaxe ajax-cleaner, plus facile à lire et à déboguer.
  2. Pour que vos utilisateurs attendent que l'ajax soit terminé, définissez un indicateur avant de demander un appel, puis désactivez-le lors du retour d'ajax. Quelle que soit la fonctionnalité à attendre pour la réponse ajax, vérifiez si l'indicateur est activé et annulez l'appel de la fonction.
  3. Attendre la fin de l'ajax précédent avant de commencer un nouvel appel sonne comme une mauvaise conception. mais pour répondre à votre question de toute façon - vous pouvez créer une chaîne d'appels ajax de sorte que chaque fois que les données sont chargées, une fonction de rappel lance l'appel ajax suivant.

Encore une fois, tout cela est beaucoup plus facile grâce à jquery. http://www.jquery.com/

+0

Merci pour votre réponse. 1) Si l'utilisation de jquery est plus facile, je le ferai certainement. 2) Ça sonne bien merci. 3) peut-être que je n'ai pas besoin de faire cela ... mais ce qui se passe actuellement est que seul le contenu de l'une des demandes AJAX est en cours d'insertion pour une raison quelconque. Si j'alerte une valeur aléatoire dans l'une des fonctions, il semble que le contenu des deux requêtes soit ajouté après avoir cliqué sur ok ... donc j'ai supposé que cela devait avoir quelque chose à voir avec l'une des fonctions achevant l'exécution avant l'autre la deuxième fonction de compléter. Désolé si c'est confus ??! –

+0

Je ne peux pas dire à partir de votre code si certaines des variables que vous utilisez sont globales. Si c'est le cas, plusieurs appels ajax peuplent la même variable lorsqu'ils renvoient des données. C'est un problème évident. JQuery fournit une solution orientée objet pour plusieurs appels ajax, ce qui facilite le suivi de la portée des variables. – Mikhail

+0

non, ils ne sont pas globaux. –