处理来自服务器的异步响应 - Javascript

时间:2014-02-18 14:56:23

标签: javascript ajax onkeyup

我工作的公司通过电话为客户提供信用申请。我们在调用应用程序之前已经拥有了大部分信息,因此我编写了一些AJAX来预先填充表单。

当操作员将其信息键入表单onKeyUp时,JavaScript会检查服务器以查看它是否可以将结果缩小到一个匹配。一旦有一个匹配,Javascript会显示一个包含用户信息的确认框。如果信息正确,则操作员点击“确定”,并使用服务器中的数据预先填充字段。

我的代码有效,但有时服务器没有立即响应,并且AJAX被称为onKeyUp,我们经常会连续多次弹出(确认)框,并且必须反复点击才能返回到表单。

我已经尝试了几种方法来防止这种情况发生。我有一个下拉列表,允许操作员在同步JavaScript和异步J之间进行选择(当设置为同步时,我们只得到一个确认,但是在服务器完成发送响应之前,用户无法输入输入字段)。我尝试了其他一些东西,但没有一个能100%工作。

以下是所实施内容的当前版本,仅针对SO进行了大量评论:) SO社区可以提供哪些建议来阻止多个确认框显示?

var showPopUp = true; // set to false once confirm is chosen to prevent additional pop ups
var stopPop = 0; // count the number of pop-ups prevented

function startAjax(){
    if(document.getElementById("flag").value == "yes" && showPopUp){ // preliminary check to avoid unnecessary calls
        if (window.XMLHttpRequest){ xmlhttpp=new XMLHttpRequest(); }else{ xmlhttpp=new ActiveXObject("Microsoft.XMLHTTP"); }

        //do stuff with server response..
        xmlhttpp.onreadystatechange=function(){
            if(xmlhttpp.readyState==4 && xmlhttpp.status==200){

                //get values from XML response..
                var status = xmlhttpp.responseXML.getElementsByTagName('status')[0].firstChild.nodeValue;
                var fname = xmlhttpp.responseXML.getElementsByTagName('fname')[0].firstChild.nodeValue;
                var addr = xmlhttpp.responseXML.getElementsByTagName('addr')[0].firstChild.nodeValue;
                var lname = xmlhttpp.responseXML.getElementsByTagName('lname')[0].firstChild.nodeValue;
                var city = xmlhttpp.responseXML.getElementsByTagName('city')[0].firstChild.nodeValue;
                var state = xmlhttpp.responseXML.getElementsByTagName('street')[0].firstChild.nodeValue;
                var zip = xmlhttpp.responseXML.getElementsByTagName('zip')[0].firstChild.nodeValue;
                var email = xmlhttpp.responseXML.getElementsByTagName('email')[0].firstChild.nodeValue;

                //show the status of the request in the status box
                document.getElementById("ajax_status").innerHTML=status;

                //if the status is "bingo" then the correct result was found, do stuff with it
                if(status == "Bingo"){

                    //make sure confirm box wasn't already shown before showing another one
                    if(showPopUp){

                        //ask user if the result returned is the correct one before populating the fields
                        var confirmMsg = "*User Found*\n\nName: "+fname+" "+lname+"\nAddress: "+addr+"\nCity: "+city+"\nState: "+state+"\nZip: "+zip+"\nEmail: "+email+"\n\nClick 'OK' To populate fields or click 'Cancel' if this is not the correct info.";
                        var fillOrNot = confirm(confirmMsg);

                        //after the user has confirmed the info from the server, set showPopUps to false to prevent additional confirm boxes, populate input values
                        if(fillOrNot){
                            showPopUp = false;
                            document.getElementById('first_name1').value = fname;
                            document.getElementById('last_name1').value = lname;
                            document.getElementById('flag').value="no";
                        }else{
                            showPopUp = false;
                            document.getElementById('flag').value="yes2";
                            document.getElementById("ajax_status").innerHTML="Aborted";
                        }
                    }else{

                        //If server returns a response after a user confirms a previous response, count the number of responses and show it in the AJAX status box
                        stopPop++;
                        document.getElementById("ajax_status").innerHTML = "Stopped "+stopPop+" pop ups";
                    }
                }                   
            }
        }

        //get parameters for request
        var param1 = document.getElementById('first_name1').value;
        var param2 = document.getElementById('last_name1').value;
        var param3 = document.getElementById('address').value;
        var url = "ajaxhandler.php?fname="+param1+"&lname="+param2+"&addr="+param3;

        //determine sync or async from drop down menu
        var e = document.getElementById("async");
        var strUser = e.options[e.selectedIndex].value;
        var asy = true;
        if(strUser == "false"){
            asy = false;
        }

        //Do request
        xmlhttpp.open("GET",url,asy);
        xmlhttpp.send(null);
    }
}

感谢您寻找

1 个答案:

答案 0 :(得分:1)

有两件事可以提供帮助:

  • 不要在“keyup”时立即启动AJAX操作。在将来的短时间内设置一个计时器(100毫秒左右),取消每个“keyup”上任何先前设置的计时器。
  • 跟踪“飞行中”是否存在AJAX操作,并忽略陈旧的AJAX结果。