【问题标题】:Abort all remaining AJAX requests中止所有剩余的 AJAX 请求
【发布时间】:2017-09-20 20:04:32
【问题描述】:

当用户在输入字段中键入然后在页面上显示结果时,我正在运行 AJAX 请求。当用户按下退格键删除他们输入的所有内容时,我使用.empty 将结果从页面中删除。

但是,如果您非常快速地按下退格键,结果将从页面中删除,但由于最后一个 AJAX 查询尚未最后执行,该查询的结果会出现!!!

我查看了Abort Ajax requests using jQuery 但这没有帮助,并尝试在$("#results").empty(); 之后添加return: false; 无济于事。

如果在if(this.value.length < 1) { 为真时还有任何剩余的 AJAX 调用,我想在该函数中中止它们。

$("input#enter").keyup(function() {
    if(this.value.length < 1) {
        $("#display").empty();
    }else{ 
        $.ajax({
            type: "POST",
            url: "getdata.php",
            data: "title=" + this.value,
            success: function(data) {
                $("#display").empty(); 
                $("#display").html(data);
            }
        });
    } 
});

【问题讨论】:

    标签: javascript jquery ajax


    【解决方案1】:

    在调用下一个$.ajax()之前,您可以使用$.active 来检查$.ajax() 调用是否处于活动状态

    $("input#enter").keyup(function() {
        if(this.value.length < 1) {
            $("#display").empty();
        }else{ 
          if (!$.active) {
            $.ajax({
                type: "POST",
                url: "getdata.php",
                data: "title=" + this.value,
                success: function(data) {
                    $("#display").empty(); 
                    $("#display").html(data);
                }
            });
          }
        } 
    });
    

    您还可以将.ajaxComplete() 附加到document 以在当前呼叫完成时呼叫下一个$.ajax() 呼叫

    function request(value) {
      return  $.ajax({
                type: "POST",
                url: "getdata.php",
                data: "title=" + value,
                success: function(data) {
                    $("#display").empty(); 
                    $("#display").html(data);
                }
            });
    }
    
    $("input#enter").keyup(function() {
        if(this.value.length < 1) {
            $("#display").empty();
        }else{ 
          if (!$.active) {
            request(this.value)
          } else {
            $(document).one("ajaxComplete", function() {
              request(this.value)
            })
          }
        } 
    });
    

    一种中止请求的方法是使用XMLHttpRequest(),将请求推送到一个数组,然后在数组的每个元素上调用.abort()

    function request(data) {
      let fd = new FormData();
      fd.append("html", data);
      fd.append("delay", Math.floor(Math.random() * 10));
      let xhr = new XMLHttpRequest();
      xhr.open("POST", "/echo/html/", true);
      xhr.onload = function() {
        console.log(xhr.responseText);
      }
      xhr.onabort = function() {
        console.log("request " + requests.indexOf(xhr) + " aborted")
      }
      xhr.send(fd);
      return xhr
    }
    
    function abortAllRequests() {
      requests.forEach(function(xhr, index) {
        xhr.abort()
      })
    }
    
    var requests = [];
    
    requests.push(request(123), request(456));
    
    abortAllRequests();
    

    jsfiddle https://jsfiddle.net/onguym5y/

    【讨论】:

    • 非常感谢,您的第一个解决方案在我看到您尚未尝试过的第二个解决方案之前对我有用,但它似乎更复杂 - 使用它而不是 if (!$.active) { 有什么好处?
    • 第二个选项将 jQuery ajaxComplete 附加到 document 如果 $.ajax() 请求处于活动状态,则在 ajaxComplete 处理程序中,当前一个 $.ajax() 调用完成时,将调用下一个 $.ajax() 请求。
    • 我已经尝试了您的第二种解决方案,但在用户停止输入后,似乎不再出现“新”结果。相反, div 在显示第一个字母的结果后会清空。虽然仍然发出 AJAX 请求,但没有发送数据 - 它显示“未定义”
    • 理想情况下,我想在函数if(this.value.length &lt; 1) {中取消我原始代码中所有剩余的ajax请求
    • 你能创建一个jsfiddlejsfiddle.net来演示吗?一种解决方案是在 HTML 中包含一个 &lt;input type="button"&gt; 元素,供用户在用户决定提出请求时按下。
    【解决方案2】:

    您谈到中止 ajax 请求。等到请求返回然后什么都不做就足够了。是的,如果您正在执行大量大型请求,则取消它们可能会提高性能。但这意味着使用 jqXhr 对象,而且我个人更喜欢尽可能坚持使用 jQuery。

    您可以有一个变量告诉您​​#display 的最新程度。它将存储用于更新它的最后一个 ajax 请求的发送时间。如果您从较早的请求中得到响应,请忽略它。

    var lastUpdateTime = 0;
    
    $("input#enter").keyup(function() {
        var now = new Date().getTime();
        if(this.value.length < 1) {
            $("#display").empty();
            lastUpdateTime = now;
        }else{ 
            $.ajax({
                type: "POST",
                url: "getdata.php",
                data: "title=" + this.value,
                success: function(data) {
                    if (now < lastUpdateTime) {
                        return;
                    }
                    $("#display").empty(); 
                    $("#display").html(data);
                    lastUpdateTime = now;
                }
            });
        } 
    });
    

    【讨论】:

      猜你喜欢
      • 2018-05-28
      • 1970-01-01
      • 1970-01-01
      • 2014-10-15
      • 1970-01-01
      • 2010-12-20
      • 2015-08-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多