【问题标题】:Is setting interval right way to make sure Ajax call is completed?设置间隔是否正确以确保完成 Ajax 调用?
【发布时间】:2012-06-15 01:09:41
【问题描述】:

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

<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()完成并填写searchResult文本字段之前,触发myButtononclick event

  3. 在 onclick 事件处理程序中,验证失败,因为 searchResult 字段仍为空。

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

理想情况下,首先完成 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);  
});

【问题讨论】:

  • 点击保存后,检查请求是否正在进行,等待它完成,然后调用 validate-save 函数。另一个问题可能是您更改输入的速度太快,并且请求进入竞争状态,因此您必须停止第一个或忽略它。
  • $.active 可以在这里作为一个选项..

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


【解决方案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"); 
     }):
 });

【讨论】:

  • 你的意思是“myButton”的点击事件会在“myButton”中删除disabled属性后立即触发?如果是这样我不知道可以通过这种方式控制事件触发时间。
  • 我试过上面的代码,由于按钮被禁用,点击事件不会在更改事件后触发。
  • 嘿,上面的代码禁用按钮,直到接收到数据。然后重新启用该按钮。 (因为在呼叫返回之前按下按钮并不是一个真正有效的选项。)我希望这会有所帮助。
  • 我知道你的意图,但我测试了你的代码并且点击事件没有触发。禁用元素不会触发鼠标事件。
【解决方案2】:

我认为为了避免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");

});

500ms的判断是根据onchange事件中post-ajax的过程需要多长时间。在我的例子中,onchange 事件中的 ajax 后处理只是将响应文本放入文本字​​段,因此 500 毫秒就足够了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-20
    • 1970-01-01
    • 2020-12-14
    相关资源
    最近更新 更多