AJAX:我如何解决需要同步请求的问题?

时间:2010-11-23 18:54:18

标签: php ajax asynchronous

我正在删除之前提出的问题并再次更简洁地问我现在对这个问题有了更多的了解。

我有一个使用大量AJAX的页面,并且更新并动态填充内容(表单元素和div与其他表单元素返回的文本)。

我真的需要强制用户等到AJAX请求被处理之后(例如,在他们完成提交了一些值的文本字段之后)才能继续。从我使用同步请求收集的内容可能会导致浏览器挂起等问题......

我还需要一个执行多个AJAX函数调用的javascript函数,但我还需要它们一次执行一个。目前使用异步调用会产生不可预测的结果......也许我会以错误的方式解决这个问题。有很多代码,所以很难提供一个简短的例子,但我会在下面试一试:

从下面(它本身由Ajax函数插入)动态地向页面添加更多表单元素,如果它是第一次编辑输入(第一次将内容写入数据库...随后它将只更新现有的数据库条目,我不需要添加其他表单项)

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

调用:

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

2 个答案:

答案 0 :(得分:1)

可能有更好的方法来解决您的整体任务,但无论如何都可以提出几点:

  1. 学习jquery并将其用于ajax - 更清晰的语法,更易于阅读和调试。
  2. 要让您的用户等待ajax完成,请在请求呼叫之前设置一个标志,并在ajax返回时取消设置。无论什么功能需要等待ajax应答检查标志是否已设置并中止函数调用。
  3. 在开始新的通话之前等待之前的ajax完成听起来像是一个糟糕的设计。但无论如何要回答你的问题 - 你可以创建一个ajax调用链,这样每次加载数据时,回调函数都会启动下一个ajax调用。
  4. 同样,通过jquery可以更轻松地完成所有这些工作。 http://www.jquery.com/

答案 1 :(得分:0)

当我第一次盯着回答这个问题时,我错误地认为你正在使用ajax。正如米哈伊尔所说,你应该真正了解这一点,它使事情变得更容易,更简单,更清洁

我认为我可以用类似的答案回答你的两个问题。

就第一个问题而言,您是对的,执行同步请求会在等待请求返回时锁定浏览器进程。您可以做的就是让它在您等待结果返回或使其不可编辑时,UI的下一部分是不可见的。以下是可以执行此操作的ajax请求的示例:

  

$。ajax({url:“test.html”,context:document.body,success:function(){           //使ui可编辑         }});

同样,对于你的第二个问题,你可以嵌套它们:

  

$ .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");

      }});

   }});
     

}});