设置间隔是否正确以确保Ajax调用完成?

时间:2012-06-15 01:09:41

标签: javascript jquery ajax javascript-events event-handling

我有两个输入文本字段和一个“保存”按钮。

<input type="text" id="myInput" />
<input type="text" id="searchResult"/>
<button id="myButton>save</button>

myInput文本字段包含 onchange事件,然后发送Ajax请求以获取一些数据并将结果显示到searchResult文本字段。

“保存”按钮具有点击事件,用于验证searchResult文本字段的输入是否为空字符串等。如果可以,那就继续保存。

$("myInput").change(function() {
    var userInput = $("myInput").val(); //get value from the text field
    var responseText = callAjaxToGetData(userInput):  //XHR request to get some data

    $("searchResult").val( responseText ); //show the XHR result here

});


$("myButton").click(function() {
    var searchResultField = $("searchResult").val(); //get value from the searchResult field
    var isOK = validate(searchResultField);  //check empty string and such

    if(isOK) { saveDataViaAjax(userInput); }
});

问题

当用户在文本字段中输入某些文字,然后点击“save"按钮

  1. onchange event被触发,callAjaxToGetData()被调用。 (XHR)

  2. 完成callAjaxToGetData()之前的
  3. 并填写searchResult文本字段,触发myButton onclick event

  4. 在onclick事件处理程序的一侧,验证失败,因为searchResult字段仍为空。

  5. callAjaxToGetData()终于完成并填写searchResult文本字段。

  6. 理想情况下,首先完成callAjaxToGetData(),然后继续执行onclick事件中的进程,以便验证不会失败。

    这似乎很常见,人们会面对这种情况,所以我想知道你们是如何处理这个问题的?

    我正在考虑将间隔放入onclick事件,如下所示(这需要responseText作为全局变量)

    $("myButton").click(function() {
    
       var interval = setInterval(function() { //call every 500ms
    
           //if responseText is not null that means i know the ajax inside of onchange event is completed for sure.
           if( responseText != null ) {
    
               clearInterval(interval);
    
               var searchResultField = $("searchResult").val(); //get value from the searchResult field
               var isOK = validate(searchResultField);  //check empty string and such
    
               if(isOK) { saveDataViaAjax(userInput); }
           }
       }, 500);  
    });
    

2 个答案:

答案 0 :(得分:1)

下面的代码可能不准确但我会在ajax之前禁用该按钮并在回调返回后启用。

$("myInput").change(function() {
     $("myButton").attr("disabled", "disabled");
     var userInput = $("myInput").val(); //get value from the text field
     var responseText = callAjaxToGetData(userInput, function(data) {

        $("searchResult").val( data); //show the XHR result here
        $("myButton").removeAttr("disabled"); 
     }):
 });

答案 1 :(得分:0)

我认为为了避免onClick event进程比onChange event中的ajax进程更快,设置计时器解决了问题。

首先,我创建了一个辅助函数,它检查活动的ajax连接并调用在onClick事件中调用的函数。

<强>辅助

function check_pending_process(callback) {
    var interval = setInterval(function() {
        if($.active > 0) {
            //do nothing here
        }
        else {
            //no ajax is running, call the function after 500 ms
            clearInterval(interval);
            setTimeout(function() { window[callback].call() }, 500);
        }    
    }, 100);
}

<强>呼叫者

function processButtonClick() {
    var searchResultField = $("searchResult").val(); //get value from the searchResult field
    var isOK = validate(searchResultField);  //check empty string and such

    if(isOK) { saveDataViaAjax(userInput); }

}

$("#myButton").click(function() {

    check_pending_process("processButtonClick");

});

500毫秒判断是基于onchange事件中ajax后的过程需要多长时间。在我的例子中,onchange事件中的ajax后进程只是将响应文本放入文本字​​段,所以500毫秒就够了。