Danny Browne
Danny Browne

Reputation: 293

AJAX: how do i get around the problem of needing synchronous requests?

I'm deleting a previously asked question and asking again more succinctly now that I have a bit more understanding of the problem.

I have a page that uses a lot of AJAX and is updated and dynamically populated with content (form elements and div's with text returned from other form element).

I really need to be able force users to wait until AJAX requests are processed (for example after they have completed a text field that has submitted some values) before they continue. From what I gather using synchronous requests can cause problems with the browser hanging etc...

I also need to have a javascript function that executes multiple AJAX function calls but i also need them to execute one at a time. Currently using asynchronous calls produces unpredictable results... maybe I'm going about this the wrong way. There is a lot of code so it's hard to provide a short example but I'll give it a try below:

The from below (which is itself inserted by an Ajax function) dynamically adds more form elements to the page if it is the first time the input has been edited (first time the content is written to the database... subsequently it will just update the existing db entry and I don't need to add the additional form items)

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

Invokes:

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

Upvotes: 0

Views: 278

Answers (2)

Kyle Gibbons
Kyle Gibbons

Reputation: 450

When I first stared to answer this question I incorrectly assumed you were using ajax. As Mikhail stated, you should really learn that, it makes things much easier, simpler, and cleaner

I think I can pretty much answer both of your questions with similar answers.

As far as the first question, you're right, doing synchronous requests will lock up the browser process while it waits for the request to return. What you can do is either make it so the next part of the UI is invisible while you wait for the results to return or make it uneditable. Here is an example of an ajax request that could do that:

$.ajax({ url: "test.html", context: document.body, success: function(){ // make ui editable }});

Similarly, for your second question, you can just nest them:

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

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

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

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

      }});

   }});

}});

Upvotes: 0

Mikhail
Mikhail

Reputation: 9007

There may be a better approach to solving your overall task, but several points can be made regardless:

  1. Learn jquery and use that for your ajax -- cleaner syntax, easier to read and debug.
  2. To make your users wait for ajax to be done set a flag before requesting a call, and unset it when ajax returns. Whatever functionality needs to wait for ajax answer check if the flag is set and abort the function call.
  3. Waiting for previous ajax to finish before starting a new call sounds like a bad design. but to answer your question anyway -- you can create a chain of ajax calls such that each time data is loaded, a callback function starts the next ajax call.

Again, all of this is much easier through jquery. http://www.jquery.com/

Upvotes: 1

Related Questions