【问题标题】:Handling Asyncronous Responses from the server - Javascript处理来自服务器的异步响应 - Javascript
【发布时间】:2014-02-18 14:56:23
【问题描述】:

我工作的公司通过电话为客户处理信用申请。在他们致电申请之前,我们已经掌握了他们的大部分信息,因此我编写了一些 AJAX 来预填充表单。

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

我的代码可以工作,但有时服务器不会立即响应,并且在调用 AJAX 时,我们经常会连续收到多个弹出(确认)框,并且必须一遍又一遍地点击 OK 才能返回表单。

我已经尝试了几种方法来防止这种情况发生。我有一个下拉菜单,允许操作员在同步 JavaScript 和 Async Js 之间进行选择(当设置为同步时,我们只会得到一个确认,但在服务器完成发送响应之前,用户无法输入输入字段)。我尝试了其他一些方法,但都没有 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);
    }
}

感谢收看

【问题讨论】:

    标签: javascript ajax onkeyup


    【解决方案1】:

    有两件事可以提供帮助:

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

    【讨论】:

    • 哇......这比我预期的要有效得多。添加 setTimeOut 似乎可以 100% 解决问题。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2013-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-02
    相关资源
    最近更新 更多